Reputation: 233
I need to create a simple crud using httpclient
How can I get the request data correctly for this nested json?
JSON
{
"resource": {
"date": "2018-03-28T11:30:00",
"observation": "truck stop schedule",
"place": "truck garage"
},
"errors": null,
"message": null
}
Service
get(id: number){
return this.http.get(environment.apiUrl + id + "/stopschedule")
.catch(this.errorHandler);
}
delete(id: number) {
return this.http.delete(environment.apiUrl + id + "/stopschedule")
.catch(this.errorHandler);
}
update(Travel, id: number) {
return this.http.put(environment.apiUrl + id + "/stopschedule", Travel)
.catch(this.errorHandler);
}
errorHandler(error: HttpErrorResponse) {
return Observable.throw(error.message)
}
Model
export class Travel {
date: Date;
place: string;
observation: string;
}
export class ResponseDetails {
errors:string;
message : string;
}
import { Travel} from './travel';
export class Response extends ResponseDetails{
travel : Travel;
}
Component.ts
//Get data
this.getData = this.travelService.get(this.id)
.subscribe(result => this.data = result['resource'], result => this.erro = true);
I tried this way but my request is returning an undefined object.
Upvotes: 0
Views: 3580
Reputation: 1451
If you'r using the HttpClient
API I'd suggest you change your model to something like this:
class ServerResponse<T> {
resource: T;
errors: string;
message: string;
}
class Travel {
date: Date;
place: string;
observation: string;
}
Then map your server requests like:
get(id: number): Observable<ServerResponse<Travel>>{
return this.http.get<ServerResponse<Travel>>(`${environment.apiUrl}${id}/stopschedule`);
}
Then in your component:
this.getData = this.travelService.get(this.id)
.subscribe(
result => this.data = result.resource,
() => this.erro = true
);
Upvotes: 0
Reputation: 57941
in the service use "map" to change the response
get(id: number){
return this.http.get(environment.apiUrl + id + "/stopschedule")
.map(response=>response.resource); //NOT return response, just response.resource
.catch(this.errorHandler);
}
Upvotes: 1
Reputation: 714
Your API looks strange, but could be only a explanation problem. It makes sense as a response, where errors and message are in the payload, but not as post, and if that is the case, the answer by @krystianpe is the correct way, I must add that if using the new HttpClient the map from json is done automatically if angular can figure out that is a json (response-type: application/json header from server or similar).
Anyway I will quick explain on a way that I think is a better idiomatic REST API:
Creating a new schedule
POST: http://localhost/api/schedule Body: { "date": "2018-03-28T11:30:00", "observation": "create a new schedule", "place": "truck garage" }
Return all active schedule
GET: http://localhost/api/schedule
If you need filter you have two options:
Editing a schedule:
PUT: /api/schedule/1
Body: { "date": "2018-03-28T11:30:00", "observation": "new observation", "place": "new place" }
You have two options: 1. Pass the whole object and update all properties (simplest) 2. Pass only the properties who are being altered.
Deleting is as simple as
Delete: /api/1
If you need to vinculate what truck has the schedule you put that on the payload (body): { "date": "2018-03-28T11:30:00", "observation": "new observation", "place": "new place", "truck_id": 1 }
To start/stop a schedule, which is your main problem, I think, you have more flexibility. Here are some ways:
PUT: /api/schedule/1/start PUT: /api/schedule/1/stop
PUT: /api/schedule/1/actions BODY: {"state": "start", "when": "now"}
PUT is to indicate you are updating somehow the state of system. But that looks like you have a relationship with a "Start" object or "Actions" object and is changing this. So I whould prefer:
PUT/POST/GET: /api/schedule/1/actions/start
Use PUT to indicate the action is idempotent (which is a confuse word), that changes only the schedule and have no other side effect. Which I think is the case. Use POST to indicate a action which is not idempotent, the side effects are unknow or affect others. USE GET to invoke a action that is ready-only and has not side effects in the system (send a email for example)
You can and should, pass parameters in the body (in this case you are configuring the start parameters), except from GET (makes no sense, use URLParams)
This is explained in more detail in https://github.com/restfulobjects/restfulobjects-spec/blob/2180261f47b7e9279bdb18180ffbee1430b1e342/restfulobjects-spec.pdf?raw=true
There is a discursion in stackoverflow: REST actions and URL API design considerations
Upvotes: 0
Reputation: 136
Your result
is probably not json body but whole response object so it doesn't contain resource
property. To retrieve the body from response you need to call json()
method:
this.getData = this.travelService.get(this.id)
.map(response => response.json())
.subscribe(result => this.data = result['resource'], result => this.erro = true);
Upvotes: 0