karlo1zg
karlo1zg

Reputation: 181

How to get json value from Angular2 app

I need to get values from a JSON file which is served from fake-json-server. To be precise, I need an exact value, e.g. I need to get all "type": "values" where group is Air.

I'm using Angular2 with TypeScript and here is a part of the code where I'm doing a get request in the TransformerService file:

getVehicleGroups(groupName: string) {
    return this.http.get(`${this.apiUrl}/vehicleTypes?group=${groupName}`)
    .map((res: Response) => res.json() as VehicleTypes[]).catch(this.handleError);
}

Exported class:

export class VehicleTypes {
     // vehicleGroup: string;
     vehicleType: string;
     vehicleModel: string;
}

And here I'm calling that method in the separate file:

getVehicleGroups() {
    return this.transformersService.getVehicleGroups(this.vehicleGroup)
    .subscribe((vehicleTypes => this.vehicleTypes = vehicleTypes));
}

The url of the fake-server "http://localhost:3000/vehicleTypes" and this is the code from db.json on that server (url):

    [
      {
        "group": "Air",
        "type": "Plane",
        "model": "F-22"
      },
      {
        "group": "Air",
        "type": "Plane",
        "model": "Sukhoi"
      },
      {
        "group": "Air",
        "type": "Plane",
        "model": "MiG"
      },
      {
        "group": "Air",
        "type": "Helicopter",
        "model": "Apache"
      },
      {
        "group": "Air",
        "type": "Helicopter",
        "model": "Kamov"
      }
      {
        "group": "Sea",
        "type": "Boat",
        "model": "Sailboat"
      },
      {
        "group": "Sea",
        "type": "Boat",
        "model": "Jetboat"
      },
      {
        "group": "Sea",
        "type": "Submarine",
        "model": "Standard"
      },
      {
        "group": "Land",
        "type": "Car",
        "model": "Camaro"
      },
      {
        "group": "Land",
        "type": "Car",
        "model": "AMG GT R"
      },
      {
        "group": "Land",
        "type": "Car",
        "model": "Lamborghini"
      },
      {
        "group": "Land",
        "type": "Truck",
        "model": "Unimog"
      },
      {
        "group": "Land",
        "type": "Truck",
        "model": "Western Star 5700"
      }
    ]

I need to mention, all my files are set well. I don't get any errors, I'm just not getting the right values..

Upvotes: 1

Views: 717

Answers (3)

CharanRoot
CharanRoot

Reputation: 6325

I need to get all "type": "values" where group is Air

First you need do filter your json result to get Air group only.

You can apply observable filter

getVehicleGroups(groupName: string) {
    return this.http.get(`${this.apiUrl}/vehicleTypes?group=${groupName}`)
    .filter(data => data.group === "Air")
    .map((res: Response) => res.json() as VehicleTypes[]).catch(this.handleError);
}

Second your VehicleTypes model variable names are different with json response so how will angular convert your json array into VehicleTypes array. you need change VehicleTypes class or your backend code send match variables name.

export interface VehicleTypes {
        type: string;
     model: string;
}

Upvotes: 1

msanford
msanford

Reputation: 12247

You do not need a class in this case, a type interface will suffice since you don't have (or seem to need) any methods in your vehicle, you're only using it for type assertion.

A class exists in the emitted JavaScript incurring unnecessary overhead, whereas an interface provides type safety without emitting classes to JavaScript: it's only used by the type-checker in tsc and then discarded.

export interface VehicleTypes {
     // vehicleGroup: string;
     vehicleType: string;
     vehicleModel: string;
}

Declare the type that your service returns:

getVehicleGroups(groupName: string): Observable<VehicleTypes[]> {
    return this.http.get(`${this.apiUrl}/vehicleTypes?group=${groupName}`)
      .map(res.json)
      .catch(this.handleError);
}

And consume it in your Component as:

// Assert the type vehicleTypes expects
vehicleTypes: <VehicleTypes>[];

getVehicleGroups() {
    return this.transformersService.getVehicleGroups(this.vehicleGroup)
    .subscribe(vehicleTypes => this.vehicleTypes = vehicleTypes);
}

Note that you don't need the (res: Response) assertion in the chain from http.get: that's what get is typed to return anyway so the type-checker already knows what to expect. Since you can remove the parameter, you can make the chain even shorter, as you did with .catch.

Upvotes: 0

Mark Cutajar
Mark Cutajar

Reputation: 340

  1. Adjust the brackets of your method.

From:

getVehicleGroups() {
    return this.transformersService.getVehicleGroups(this.vehicleGroup)
    .subscribe((vehicleTypes => this.vehicleTypes = vehicleTypes));
}

To:

getVehicleGroups() {
    return this.transformersService.getVehicleGroups(this.vehicleGroup)
    .subscribe((vehicleTypes) => this.vehicleTypes = vehicleTypes);
}
  1. Map the data with your model:

Option 1: Change the model to match the json data.

export class VehicleTypes {
     type: string;
     model: string;
}

Option 2: Change the json properties at service level, right after converting to json.

getVehicleGroups(groupName: string) {
    return this.http.get(`${this.apiUrl}/vehicleTypes?group=${groupName}`)
    .map((res: Response) => res.json().map(res => new VehicleTypes(res.type, res.model)).catch(this.handleError);
}

and you would need to create a constructor for the VehicleTypes.

Upvotes: 0

Related Questions