# 10.10: Marking Messages as Read

Our last thing to add for our messages is the functionality to mark messages as read.

This would be a good challenge for you to try to implement on your own. It uses most of the skills we learned in the course!

## Adding Service Method

First, we'll add a method signature to our `IMessageService.cs` class:

```csharp
Task<bool> MarkMessageAsRead(Message message);
```

Next, we'll implement it in `MessageService.cs`:

```csharp
public async Task<bool> MarkMessageAsRead(Message message)
{
    message.IsRead = true;
    message.DateRead = DateTime.Now;

    return await SaveAll();
}
```

Much more manageable than some of our previous service methods!

## Add Controller Method

```csharp
[HttpPost("{id}/read")]
public async Task<IActionResult> MarkMessageAsRead(int userId, int id)
{
    if (userId != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
        return Unauthorized();

    var message = await _messageService.GetMessage(id);

    if (message.RecipientId != userId)
        return BadRequest("Failed to mark message as read.");

    if (await _messageService.MarkMessageAsRead(message))
        return NoContent();

    throw new Exception("Error deleting the message");
}
```

## Add Service Method in Angular

In `user.service.ts` - add a new method called `markAsRead()`

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

We can make the method here self-subscribing, which means we don't have to subscribe to it in our component and write a separate method - we can just use it in `loadMessages()` in our `member-messages.component.ts`.

First, let's import the `do` operator from `rxjs`. This will allow us to 'do' something with the messages array before we subscribe to it. In our case, we want to check if the messages are marked as read.

We'll also bring in `underscore` again.

```typescript
import 'rxjs/add/operator/do';
import * as _ from 'underscore';
```

```typescript
loadMessages() {
    const currentUserId = +this._authService.decodedToken.nameid;                                   //  1.
    this._userService.getMessageThread(currentUserId, this.userId)                                  //  2.
      .do(messages => {                                                                             //  3.
        _.each(messages, (message: Message) => {                                                    //  4.
          if (message.isRead === false && message.recipientId === currentUserId) {                  //  5.
            this._userService.markAsRead(currentUserId, message.id);                                //  6.
          }
        });
      })
      .subscribe(messages => {
        this.messages = messages;
      }, error => {
        this._alertify.error(error);
      });
}
```

This is a bit trickier in the JavaScript/TypeScript than what we've done so far. But, think back to how we're manipulating data in some of our service methods on the backend with LINQ and it's very relatable.

1. Since we need it again, we'll store this in a variable this time to make it reusable.
2. We're calling our service method as usual - but, changing the first parameter to the variable we just created.
3. We're calling the `rxjs` `do` operator that let's us 'do' something with the data before we subscribe to it.
4. This is what we're 'doing': we're using the `underscore` `each()` function to loop through an array and apply a callback function to each element.
5. In the callback function, we're checking if the message isn't marked as read and if the user that is loading the messages is the recipient.
6. If so, we call the `markAsRead()` function we just wrote.

## Test It!

Open up the browser, log in as one user in a message conversation - navigate to the `MemberMessage` component, view the messages, and then log in as the other user.

See if the `IsRead` property has updated:

![MessagesRead](/files/-LAU8txK_ziEas5nw1sT)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://eleven-fifty-academy.gitbook.io/dotnet-302-core/10-messaging/10.10-marking-messages-as-read.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
