0

I have a simple JSON file which returns an array of objects in format:

[
    {
        "id": 1,
        "url": "file/abc.txt"
    },
    {
        "id": 2,
        "url": "file/def.txt"
    }
]

I am accessing the service as given below:

this.http.get("json-url")
.map((response) => response.json())
.filter((file) => file.id === 1)

It doesn't work anything. However if I use mergeMap instead, it works fine.

this.http.get("api-url")
.mergeMap((response) => response.json())
.filter((file) => file.id === 1)

I have used map operator earlier and it worked. However it is not working here. Please let me know if I am mistaking anything while using map operator.

Please note- I am using angular 6.

6
  • which version of RxJs are you using? If you are using RxJs 6 or above, you have to use the pipe operator, whereas earlier version allows you to directly apply map operator on an Observable. Commented Dec 11, 2018 at 13:47
  • Can you elaborate on "this doesn't work"? Commented Dec 11, 2018 at 13:48
  • 1
    rxjs version - 5.5.6 Commented Dec 11, 2018 at 13:48
  • @pgreen2: updated question Commented Dec 11, 2018 at 13:49
  • add the error message you are encountering. Commented Dec 11, 2018 at 13:51

3 Answers 3

1

If you're running Angular 6, it's really recommended to use HttpClient as Http is deprecated. Now since you'd be using HttpClient you won't need to call .json method on the response as that is something that HttpClient takes care of implicitly.

Also, since Angular 6 uses Rxjs 5.5 or later, you can't directly chain the operators like map and pipe to an Observable. You'll have to call the pipe function on an Observable value and add the list of operators that you want to you separated by a ,.

import { HttpClient } from '@angular/common/http';
import { map, filter } from 'rxjs/operators';

...

constructor(private http: HttpClient) {}

...

return this.http.get("json-url")
  .pipe(filter((file) => file.id === 1));

Here, I'm returning the Observable so that I can subscribe to it from the place I'm calling the function that is wrapping this piece of code.

To make sure that HttpClient works correctly, you'll also have to import HttpClientModule in your @NgModule file and add it to the imports array.

Sign up to request clarification or add additional context in comments.

Comments

1

Important to understand here is that this.http.get("json-url") returns an observable. It won't be executed until you subscribe. You must subscribe to send the request.

this.http.get("json-url") .map((response) => response.json()) .filter((file) => file.id === 1) .subscribe(theResultAfterMapAndFilter => console.log(theResultAfterMapAndFilter));

The reason why mergeMap works is that it subscribes to the source observable internally (if I'm not mistaken).

Comments

0

I have an answer for why map isn't working, but i'm not entirely sure why mergeMap is working. The object returned from response.json() is any list. So the filter should handle the full list. Not the individual elements of the list. The list has not property of id so nothing matches. Even though the parameter in filter is called file, it should be files. I believe the following will work with map:

this.http.get("json-url")
.map((response) => response.json())
.filter((files) => files.filter((file)->file.id === 1));

However, you would get a list back. If you really want a single file, you could add in another map:

this.http.get("json-url")
.map((response) => response.json())
.filter((files) => files.filter((file)->file.id === 1))
.map(files=> files[0]);

With all of that said, I think the reason mergeMap worked might be some older quirk of rxjs. My unverified guess is that list returned from the anonymous function is being converted into an observable by mergeMap. That seems a bit fishy, but could be possible. The older rxjs API seemed to try to make things work even if it probably shouldn't.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.