问题
I have a problem with transforming my observable. Details below:
I have a data like this
[
{
'firstName': 'John',
'lastName': 'Cash',
'age': 20
}
];
Then I get this data from api:
public getData(): Observable<Data[]> {
return this.http.get('xxx')
.map(
response => response.json()
);
}
Then, I'm trying to subscribe this:
this.service.getData.subscribe(
(res) => this.data = res
);
And It's ok, it's working. But I need to modify the structure of object and I would like to use .map to transform received object to this schema:
[
{
'firstName': 'John',
'lastName': 'Cash',
'age': 20,
'newProperty': 'value'
}
];
.. and nothing working for me.. :/ Even if I don't want to add new property, but modify a value on for example firstName:
.map(
return x => x[0].firstName = 'asd'
)
it's not working (Type 'string' is not assignable to type 'Data[]', I know what it means, but I don't know how to do that, where is my mistake?)
回答1:
There's a difference between map operator in Observable and map operator in array. You want to transform the result of HTTP request to array and then apply some additional transformation to every member of that array.
this.http.get('...')
This returns the Observable object, which holds the Response of angular's Http service. To make use of the data inside of it, you have to call Response's json() method.
.map((response:Response) => response.json())
This code means 'when the observable sends some data, treat it as HTTP response and extract its content as JSON, then put to another Observable'. So if you subscribe to it, you'll get your array. The you can do anything with that regular array, like using map operator. Let me use my own example though it's very similar to yours.
this.http.get('...')
.map((response:Response) => response.json())
.subscribe((array:Person[]) => {
let modifiedArray = array.map((item:any) => {
item.newProperty = 'value';
}
this.persons = modifiedArray;
});
Or, if you like to, manipulate array items before subscription:
let modifiedData$:Observable<Person> = this.http.get('...')
.map((response:Response) => response.json())
.map((array:Person[]) => {
return array.map((item:Person) => {
item.newProperty = 'value';
}
};
Two consecutive map operators are not needed:
let modifiedData$:Observable<Person[]> = this.http.get('...')
.map((response:Response) => {
return response.json().map((item:Person) => {
item.newProperty = 'value';
}
};
modifiedData$.subscribe((persons:Person[]) => {
this.persons = modifiedArray;
});
If it's too wordy to you, here's a more compact (but less readable) version:
this.http.get('...')
.map(response => response.json().map(item => item.newProperty = 'value'))
.subscribe(persons => this.persons = persons);
回答2:
you have to create object of that type , for example as below
.map((res: Response) => res.json().map(obj => new MyObject(obj.id, obj.name)))
来源:https://stackoverflow.com/questions/46197223/transforming-observable-with-map