How to extract field from API response struct to another struct field while changing datatype?

Viewed 40

I'm using range to loop through an array of structs to extract data which will be used as a URL parameter for my API calls. Within this loop, I'm trying to push response data from one struct to another.

I'm able to get everything working, except for moving data from one struct to another, but not entirely sure how to solve for the errors I keep getting. I've tried multiple methods and seem to be stuck in the mud here for something I don't consider to be too hard, until now... In my code I'm using the append method but I'm not so sure that might be the correct way to proceed.

Presenting my code:

models.go

//Here is my existing struct, with populated data that I get from a CSV
type TravelItenaries struct {
    Origin                string
    Destination           string
    Flight_num            string
    Origin_latitude       string
    Origin_longitude      string
    Destination_latitude  string
    Destination_longitude string
    Origin_weather        string
    Destination_weather   string
    Coordinates_ori       string
    Coordinates_dest      string
    Temp_c_ori            string
    Temp_f_ori            string
    Temp_c_dest           string
    Temp_f_dest           string
}

//Here is the response data that I'm expected to get from my API calls.
//I'm trying to "push" Temp_c_dest and Temp_f_dest data into TravelItenaries.Temp_f_dest and TravelItenaries.Temp_c_dest 
//While also changing the data types to fit above.
type Response struct {
    Current struct {
        LastUpdatedEpoch int     `json:"last_updated_epoch"`
        LastUpdated      string  `json:"last_updated"`
        Temp_c_dest      float64 `json:"temp_c"`
        Temp_c_dest      float64 `json:"temp_f"`
        IsDay            int     `json:"is_day"`
  } `json:"current"
}

weather.go


func (s *Server) getWeather(w http.ResponseWriter, r *http.Request) {
    // open file
    f, err := os.Open("challenge_dataset.csv")
    if err != nil {
        responses.ERROR(w, http.StatusBadRequest, fmt.Errorf("helpful error"))
        return
    }

    // remember to close the file at the end of the program
    defer f.Close()

    // read csv values using csv.Reader
    csvReader := csv.NewReader(f)
    data, err := csvReader.ReadAll()
    if err != nil {
        responses.ERROR(w, http.StatusBadRequest, fmt.Errorf("helpful error"))
        return
    }

    // convert records to array of structs
    travelItenaries := createTravelItenaries(data)

    // remove duplicate flight records
    cleanTravelItenaries:= remDupKeys(travelItenaries)

    // set up params for API get request
    params := url.Values{
        "key": []string{"xxx"},
        "q":   []string{""},
    }
    
    // Construct URL for API request
    u := &url.URL{
        Scheme:   "https",
        Host:     "api.weatherapi.com",
        Path:     "/v1/current.json",
        RawQuery: params.Encode(),
    }

    client := &http.Client{}

    // Will need this to populate the params using a range over a struct
    values := u.Query()


    // loop through cleaned data set
    for _, service := range cleanTravelItenaries {
        
        // dynamically acquire data from struct to pass as parameter
        values.Set("q", service.Coordinates_dest)
        u.RawQuery = values.Encode()

        req, err := http.NewRequest("GET", u.String(), nil)
        if err != nil {
            responses.ERROR(w, http.StatusBadRequest, fmt.Errorf("helpful error"))
            return
        }

        resp, err := client.Do(req)
        if err != nil {
            responses.ERROR(w, http.StatusBadRequest, fmt.Errorf("helpful error"))
            return
        }
        body, err := ioutil.ReadAll(resp.Body)
        
        // create empty struct to parse response data with using Inmarshal
        var responseData models.Response
        json.Unmarshal(body, &responseData)

        // Here is the issue, I don't think append might be the correct procedure here?
        // I simply just need to pass this response data to my already existing struct
        service.Temp_c_dest = append(responseData.Current.Temp_c_dest      , cleanTravelItenaries )
        service.Temp_f_dest = append(responseData.Current.Temp_f_dest      , cleanTravelItenaries )

    }

}

The errors I get are related to both append statements at the end of the range function.

first argument to append must be slice; have float64

first argument to append must be slice; have float64

for both append methods.

Also, note how type TravelItenaries struct uses string type for:

    Temp_c_dest           string
    Temp_f_dest           string

Hence why I also need to do some field type conversion from Float64 to string.

How can I extract the fields Temp_c_dest and Temp_f_dest from API response struct to TravelItenaries struct fields while changing datatypes?

EDIT: I've managed to get this somewhat working, but only inside the for loop. The data is not being saved outside the function.

        service.Temp_f_dest = strconv.FormatFloat(responseData.Current.Temp_f_dest, 'g', -1, 64)
        service.Temp_c_dest = strconv.FormatFloat(responseData.Current.Temp_c_dest, 'g', -1, 64)
0 Answers
Related