Fahd
Fahd

Reputation: 266

In Angular How do I map a JSON response to a model where the model's and JSON's properties don't match?

My model looks like this:

export interface IFlightPlan {
        flightPlanId: string;
        aircraftIdentification: string;
        aircraftType: string;
        airspeed: number;
        altitude: number;
        flightType: string;
        fuelHours: number;
        fuelMinutes: number;
        departureTime: Date;
        arrivalTime: Date;
        departureAirport: string;
        arrivalAirport: string;
        route: string;
        remarks: string;
        numberOnBoard: string;
}

And a sample of the JSON response from my API looks like this. The API returns an array of 25 of these:

{
        "flight_plan_id":"f1d193ad0153491f9cf61cbe39c7db70",
        "aircraft_identification":"N67SVS",
        "aircraft_type":"PA-34 Piper Seneca",
        "airspeed":128,
        "altitude":12000,
        "flight_type":"VFR",
        "fuel_hours":3,
        "fuel_minutes":41,
        "departure_time":"2022-07-08T00:26:45Z",
        "estimated_arrival_time":"2022-07-08T03:49:45Z",
        "departing_airport":"KBXA",
        "arrival_airport":"KNZY",
        "route":"KBXA JOH J46 DMDUP J46 KNZY",
        "remarks":"",
        "number_onboard":4
    }

As you can see, the properties of my model and those of the JSON response differ in casing and spelling.

Here's my Angular response service:

@Injectable({
  providedIn: 'root'
})
export class FlightplansService {

  private apiUrl = "https://localhost:3001/api/v1/flightplan";

  constructor(private http: HttpClient) { }

  getFlightPlans(): Observable<IFlightPlan[]> {
    return this.http.get<IFlightPlan[]>(this.apiUrl).pipe(
      tap(data => console.log('ALL FLIGHT PLANS: ', JSON.stringify(data))),
      catchError(this.handleError)
    );
  }

  handleError(err: HttpErrorResponse) {
    let errorMessage = '';
    errorMessage = `An error has occurred: ${err.error.message}`;
    console.log(errorMessage);
    return throwError(() => errorMessage);
  }
}

and here's where I'm using it in my component

ngOnInit(): void {
    this.flightPlanService.getFlightPlans().subscribe({
     next: (data => this.flightPlans = data),
     error: (err => this.errorMessage = err)
   })

I can't access any of this.flightPlans[] children's properties. I don't quite understand what's going on by my guess is that this.flightPlans[] is assigned a generic array instead of IFlightPlan[] array because there's no way to map from the JSON to the model

How do I fix this?

Upvotes: 0

Views: 1169

Answers (1)

Jamil
Jamil

Reputation: 193

Use map inside the pipe and define a result object as IFlightPlan as flowing:

  getFlightPlans(): Observable<IFlightPlan[]> {
    return this.http.get<IFlightPlan[]>(this.apiUrl).pipe(
      map(flightPlans  => flightPlans.map(item =>  
        {
          let flightPlan: IFlightPlan  = { 
            flightPlanId: item.flight_plan_id, 
            aircraftIdentification: item.aircraft_identification,
...
          } 
          return flightPlan;
        }
        )),
      tap(data => console.log('ALL FLIGHT PLANS: ', JSON.stringify(data))),
      catchError(this.handleError)
    );
  }

UPDATE:

While you'll map the incoming data after reading so it's enough to make http.get read the data as array of any as flowing:

      getFlightPlans(): Observable<any[]> {
        return this.http.get<any[]>(this.apiUrl).pipe(
          map((flightPlans) =>
            flightPlans.map((item) => {
              let flightPlan: IFlightPlan = {
                flightPlanId: item.flight_plan_id,
                aircraftIdentification: item.aircraft_identification,

..
              };
              return flightPlan;
            })
          ),
          tap((data) => console.log('ALL FLIGHT PLANS: ', JSON.stringify(data))),
          catchError(this.handleError)
        );
      }

Don't forget to fill the right fields names from item

Upvotes: 2

Related Questions