0

I have a scenario where I need to pass lat and long separated by semicolon(;) from an array. The API will only accept maximum of 145 lat long in one request. I have a total of 100K lat long to be passed as a batch request and save/append all the responses in one json file.

Here is the steps I have tried so far.

this is my sample array of geocodes.(Total of 100K)

  this.geocodes = [
            '-39.32939098,173.80391646',
            '-35.13188244,173.43837148',
            '-35.96790802,174.22052708',
            '-39.60085901,174.27450675',
            '-46.89935626,168.12957415',
            '-40.94922683,175.66038897',
            '-40.57392064,175.39045103',
            '-37.67488205,175.06674793',
            '-37.77800560,175.22295017',
        ];

I would like to pass every nth(145) lat long as query parameters separated by semicolon in one GET request.

  getOneDayWeatherData() {
        let searchParams = new HttpParams();
        this.geocodes = [
            '-39.32939098,173.80391646',
            '-35.13188244,173.43837148',
            '-35.96790802,174.22052708',
            '-39.60085901,174.27450675',
            '-46.89935626,168.12957415',
            '-40.94922683,175.66038897',
            '-40.57392064,175.39045103',
            '-37.67488205,175.06674793',
            '-37.77800560,175.22295017',
        ];
        const output = [];
        let j = 2;
        for (let i = 0; i < this.geocodes.length; i++) {
            output.push(this.geocodes.slice(i, j));
            i++;
            j = j + 2;
        }
        console.log('output', output);
        searchParams = searchParams.append('geocodes', output.join(';')); //separated by semi colon 
        searchParams = searchParams.append('language', 'en-US');
        searchParams = searchParams.append('format', 'json');
        searchParams = searchParams.append(
            'apiKey',
            'yourAPIKey'
        );

        return this.http
            .get<{ [key: string]: Weather }>(
                `https://api.weather.com/v3/aggcommon/v3-wx-observations-current?`,
                { params: searchParams }
            )
            .pipe(
                catchError((errorRes) => {
                    // send to Analytics server
                    return throwError(errorRes);
                })
            );

        // .tap((data) => console.log('All :' + JSON.stringify(data))),
    }

As a test I was trying to pass every 2 elements from my geocodes Array but no luck.

In the component where I subscribe to this service where I would like to append all the responses in one single JSON file.

Any help is appreciated. Thank you

Ragavan Rajan
  • 4,171
  • 1
  • 25
  • 43
  • you can create multiple request list each containing 145 lat long as searchParams and then use forkjoin to combine the response. this link may help you to acheive this - https://stackoverflow.com/a/43166302/7051329 – Kishor Kunal May 27 '20 at 04:39
  • Thank you @KishorKunal. I will definitely give forkjoin try. any idea on how to iterate only 145 params in one request. – Ragavan Rajan May 27 '20 at 04:45

1 Answers1

0

You can refer to below component logic to group and make batch request.

component.ts sample

import { Component , OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { forkJoin } from 'rxjs/observable/forkJoin';
import { Observable } from 'rxjs';
import 'rxjs/add/observable/of';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  response = [];

  items : any[] =[];

  constructor() {
  }

  ngOnInit(){
    this.InitializeData();
    this.makeMultipleCall();
  }

//this is to mimic your lat long array
  InitializeData(){
    var range = 1000;
    for(var i = 0 ; i<=range ;i++)
    {
      this.items.push("item_"+i);
    };
  }

//this will group your data and make a fork join to the request.
  makeMultipleCall(){
    const requestArray = [];
    //make call for 145 items each:
    var groupedItems = this.groupByN(145 , this.items);
    groupedItems.forEach(s=>{
      requestArray.push(this.mimicHttpCall(s));
    });

    forkJoin(requestArray).subscribe(results => {
      var i = 0;
      results.forEach(s=>{
        console.log("Response " +i)
        console.log(s);
        i++
      })
      this.response = results;
    });
  }

//mimicing your http call : suppose its joins with '|'
  mimicHttpCall(list : any[]): Observable<any> 
  {
    return Observable.of(list.join("|"));
  }

  groupByN(n, data):any[]{
    let result = [];
    for (var i = 0; i < data.length; i += n) result.push(data.slice(i, i + n));
    return result;
  };
}
Kishor Kunal
  • 267
  • 1
  • 6
  • sorry I am bit confused. My http call is in service file. MimicHttpcall is making multiple request but on every request all my geocodes are passed. I am doing something wrong to make this work properly. – Ragavan Rajan May 27 '20 at 10:25
  • for your convenience: Openweather map api is providing free API key just in case to try the real API. https://openweathermap.org/. Kindly help. Thanks – Ragavan Rajan May 27 '20 at 10:31