0

I am implementing a private message system in an app that uses angular 4. When a user clicks on a unread message in their inbox (that may make up one of multiple messages in a thread that also may be unread) all the messages should be returned in the thread but I also want to check to see if any of the messages are unread, and mark them as read as part of this method.

The call to get the messages looks as follows:

getMessageThread(id: number, recipientId: number) {
  return this.authHttp.get(this.baseUrl + 'users/' + id + '/messages/' + recipientId)
    .map(response => response.json())
    .catch(this.handleError);
}

and in the component:

loadMessageThread() {
    const currentUserId = +this.authService.decodedToken.nameid;
    this.userService.getMessageThread(currentUserId, this.userId).subscribe(messages => {
      this.messages = messages;
    }, error => {
      this.alertify.error(error);
  });
}

I also have the following method in the service which should be called conditionally if any of the returned messages in the thread are marked as unread:

markAsRead(userId: number, messageId: number) {
  return this.authHttp.post(this.baseUrl + 'users/' + userId + '/messages/' + messageId, {}).subscribe();
}

So far I have tried a few different options. If I try and call the user service from within the subscribe I get an error stating the user service is undefined:

loadMessageThread() {
  const currentUserId = +this.authService.decodedToken.nameid;
  this.userService.getMessageThread(currentUserId, this.userId)
    .subscribe(messages => {
      this.messages = messages;
      _.each(this.messages, function(message) {
        if (message.read === false && message.recipientId === currentUserId) {
          console.log(message) // works
      this.userService.markAsRead(currentUserId, message.id); // fails
      }
    });
  }, error => {
    this.alertify.error(error);
  });
}

If I try using a 'do' method prior to the subscribe this also fails to call the method in the service and goes straight to the error condition without hitting the subscribe method:

  loadMessageThread() {
const currentUserId = +this.authService.decodedToken.nameid;
this.userService.getMessageThread(currentUserId, this.userId)
  .do(messages => {
    _.each(messages, function (message: IMessage) {
      if (message.read === false && message.recipientId === currentUserId) {
    console.log(message) // works
        this.userService.markAsRead(currentUserId, message.id); // fails
      }
    });
  })
  .subscribe(messages => {
    this.messages = messages;
  }, error => {
    this.alertify.error(error);
  });
}

I'm not sure if I am overthinking this and am missing a more obvious approach to this. Any help or suggestions would be appreciated.

Thanks, Neil

1
  • 1
    It looks like you're trying to chain Observables. Have a look at RxJs' mergeMap() method to achieve it. This might also be useful. Commented Sep 21, 2017 at 10:20

1 Answer 1

1
 _.each(this.messages, function (message) { 

should be

 _.each(this.messages, (message) => {

otherwise this will not refer to the component.

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

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.