Home > Software engineering >  Not getting expected result from RxJS map() operator with Angular HttpClient
Not getting expected result from RxJS map() operator with Angular HttpClient

Time:08-05

I am trying to understand the map() operator of RxJS

Below is one of the example with works as expected. In this example all names will be appended with text student one by one.

studentArray:string[]=['sam','robert','lisa'];
from(this.studentArray).pipe(map((s:string)=>s=s ' student')).subscribe(d=>console.log(d));

Now I have below sample code. With this code I am calling a service which returns array of ToDo objects. What I am tryting to do is the iterate each ToDo object and return the updated object

enter image description here

But when I do so it gives an error and reason for the error is data variable in the map operator. With above example map operator is not getting single element of an array of ToDo but the entire array is being passed to the map.

Am I doing something wrong here? Hope someone can help me in this.

EDIT: Updated image

CodePudding user response:

map() function that you use is not JavaScript standard Array.map, it is the RxJs map operator, it applies a project function to each value emitted (in your case, a single value is an array of ToDo) by the source Observable, and emits the resulting values as an Observable.

CodePudding user response:

It is not Angular-ish thing per say but it is more a Typescript compiler issue. It is doing its job correctly telling you that you are assigning something of type B to something else of type C. In our case here, it is the fact that you are assigning a string to an array of TODOs.

What @Jason White mentioning in the comment is IMO the correct answer to solve your problem.

CodePudding user response:

You are using the map operator incorrectly. The map operator receives a value, transforms it, and returns the transformed value. You are doing an assignment instead. A valid example would be:

.pipe(
   map((value: string) => value   'append')
)

Also, your data is not a single ToDo but an array, i.e. ToDo[]. So with data = data.title 'append' you are trying to assign a string to a ToDo[].

If I understand correctly, you want to append something on each ToDo's title property. Then you would have to do something like this:

this.http.get<ToDo[]>('YOU-ENDPOINT-URL-HERE').pipe(
   concatMap((dataArray: ToDo[]) => from(dataArray)), // from array to single objects
   map((data: ToDo) => {
      data.title  = 'append'; // transform tittle
      return data; // return transformed data
   }),
   toArray() // recreate array
).subscribe((d) => console.log(d));

EDIT: Your first example is not equivalent to your use-case. The from operator takes an array, in your example string[], and converts it into an Observable<string>.

The http.get<Todo[]> declares that the returned type from your backend is going to be an array. And this is the type of data that will be passed to your pipe, hence to your map operator as well.

  • Related