1

This is my first angular project, and I'm still not familiar that well with Observables and RxJS. In my project, at first I want to fetch all notifications with get request. After that, I want to take id of the last notification, so I could send post request to server to mark them all as read. So the code in service looks like this:

 getNotifications(limit: number, page: number): any {
    return this.http
      .get<INotifications>(
        `${API_URL}/notifications?direction=desc&limit=${limit}&order_by=created_at&page=${page}`
      )
      .pipe(
        switchMap((response) => {
          const id = response.data[0].id;
          return this.markNotificationsAsRead(id);
        })
      );
  }

markNotificationsAsRead(id: number) {
    return this.http.post(`${API_URL}/notifications/${id}/mark_all_as_read`, {
      id,
    });
  }

I tried with switchMap and mergeMap

operators, but I get

RangeError: Invalid array length

Code in component:

 fetchData() {
    this.notificationsService.getNotifications(this.limit, this.meta?.next_page || 1).subscribe(
      (response) => {
        this.notifications = [...this.notifications, ...response.data];
        this.meta = response.meta;
        this.isLoading = false;
        // const mostRecentNotification = response.data[0].id;
        // this.markNotificationsAsRead(mostRecentNotification);
      },
      (error) => {
        this.handleErrors(error);
      }
    );
  }

Btw: I can make it work, by deleting this commented section in fetchData function, and just returning get request without piping another operator, but I wanted to give it a try and do it in service. Any ideas why it wont work?

11
  • If you debug this, what is the value of response? Commented Feb 9, 2021 at 12:57
  • Are you intending to do return this.markNotificationsAsRead(id)? That will return the value of your post request to the fetchData() method, not the value of your get request. Commented Feb 9, 2021 at 13:02
  • I get an Object with all provided data: Object data: (5) [{…}, {…}, {…}, {…}, {…}] meta: {prev_page: null, current_page: 1, next_page: 2} proto: Object Commented Feb 9, 2021 at 13:02
  • Is that value of response the same in the switchMap() AND the fetchData() subscribe? Commented Feb 9, 2021 at 13:06
  • "Are you intending to do return this.markNotificationsAsRead(id)? That will return the value of your post request to the fetchData() method, not the value of your get request. – RJM 1 min ago" I want to return data from GET req. Commented Feb 9, 2021 at 13:13

1 Answer 1

0

So if I understand correctly, you are trying to get some data (notifications), make a post request when the data comes back, and then display the data in your component.

The problem you are encountering, is you haven't managed to make the post request from the service and get the data to the component.

The problem

The issue as I see it is here:

 switchMap((response) => {
            const id = response.data[0].id;
            return this.markNotificationsAsRead(id);
          })

What this is doing, is return the value of markNotificationsAsRead() to your subscribe not the notifications data that your are expecting.

The solution

You are correct in using switchMap() to make two requests in one. I believe all you need is one minor modification:

switchMap((response) => {
            const id = response.data[0].id;
            return this.markNotificationsAsRead(id).pipe(map(() => response));
          })

By adding the pipe(map(() => response)) you are returning the value of the first observable, while still subscribing to the second (and thus making the post request).

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

2 Comments

For sure, how can I mark it, tho? I don't have enough reputation to see my upvote :(
No worries, this link should explain: meta.stackexchange.com/questions/5234/…

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.