Home > Blockchain >  mongoose cant display private message data
mongoose cant display private message data

Time:08-27

I am pretty new with mongoose & node.js and I am having an issue with displaying my users messages privately.

The message recipient, sender and message content is stored in the database.

but when I want to see the message's between two users, the messages between two users are displayed on every user messages tab!. (developing in MEAN stack environment)

The Problem: https://i.imgur.com/qfDlMml.mp4

Messages Schema:

var messageSchema = new mongoose.Schema({

  id: {
    type: Number,
  },

  senderId: {
    type: Number
  },

  senderUsername: {
    type: String
  },

  recipientId: {
    type: Number
  },

  recipientUsername: {
    type: String
  },

  content: {
    type: String,
    required:true
  },

  dateRead: {
    type: Date
  },

  messageSent: {
    type: Date
  },

  senderDeleted: {
    type: Boolean
  },

  recipientDeleted: {
    type: Boolean
  }
},
  {
    collection: 'messages',
    timestamps: true
  },
);

module.exports = mongoose.model('Messages', messageSchema)

User route:

//Get Message Of User
usersRoute.route("/messages/thread/:username/:senderUsername").get((req, res) => {

    Messages.find(({ data: { "$in" : [req.params.senderUsername,req.params.username]} }, (error, data) => {
          if (error) {
            console.log(error)
            throw error;
          }
  
          res.json(data);
  
        }))

  })

messages.service:

  getMessageThread(username: string,sender:string) {
    return this.http.get<Message[]>(`${AUTH_API}messages/thread/${username}/${sender}`);
  }

member-messages.ts:


import { Component, OnInit, Input } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Message } from 'src/app/models/message';
import { User } from 'src/app/models/user';
import { AccountService } from 'src/app/services/account.service';
import { MessageService } from 'src/app/services/message.service';
import { Observable, take } from 'rxjs'
import { ActivatedRoute } from '@angular/router';
import { MembersService } from 'src/app/services/members.service';

@Component({
  selector: 'app-member-messages',
  templateUrl: './member-messages.component.html',
  styleUrls: ['./member-messages.component.css']
})

export class MemberMessagesComponent implements OnInit {
  @Input() username: string;
  @Input() messages: Message[];
  user: User;
  member: any;
  currentUser$: Observable<User | null>;
  messageContent: string;

  constructor(
 private messageService: MessageService,
 private accountService: AccountService,
 private route: ActivatedRoute,
 private memberService: MembersService
) {
    this.accountService.currentUser$.pipe(take(1)).subscribe(x => {

      this.currentUser$ = this.accountService.currentUser$;
      this.user = x as User;

    });
  }


  ngOnInit() {
    const username = this.route.snapshot.paramMap.get('username') as string;
    this.memberService.getMember(username).subscribe(member => { 
    this.member = member;
    });
  }

  sendMessage(form: NgForm) {
    this.messageService.sendMessage(this.username, this.messageContent, this.user)
      .subscribe((message) => {
        this.messages.push(message as Message);
  
        form.reset();
      })
  }
}

member-messages.html:

<div >
    <div >
  
      <ng-container *ngIf="messages && messages.length; else noMessages">
        <ul >
          <li *ngFor="let message of messages.slice().reverse()">

            <span >
              <img  *ngIf="message.senderUsername && member.username == message.recipientUsername" src="{{user.profile_img || './assets/user.jpg'}}"> <span *ngIf="message.senderUsername && member.username == message.recipientUsername" style="color:red"> {{message.senderUsername}}</span> <img  *ngIf="message.recipientUsername && member.username != message.recipientUsername " src="{{member.profile_img || './assets/user.jpg'}}"><span *ngIf="message.recipientUsername && member.username != message.recipientUsername" style="color:green"> {{member.username}}</span>
            </span>
            <div  >
              <p >{{message.content}}</p>
            </div>
          </li>

        </ul>
      </ng-container>
  
      <ng-template #noMessages>No messages Yet... say hi bu using the message box bellow</ng-template>
    </div>
    <div >
      <form #messageForm="ngForm" (ngSubmit)="sendMessage(messageForm)" autocomplete="off">
        <div >
          <input
          name="messageContent"
          required
          [(ngModel)]="messageContent"
          type="text"
          
          placeholder="Send a private message">
          <div >
            <button [disabled]="!messageForm.valid"  style="border-radius:0px 5px 5px 0px"type="submit"> Send </button>
  
          </div>
        </div>
      </form>
    </div>
  </div>
  

CodePudding user response:

I think the problem is that you are trying to query for the data field but this field does not exist in your data model. Solution is to ask data model for messages which contain senderUsername and recipientUsername in the database.

usersRoute
  .route("/messages/thread/:username/:senderUsername")
  .get(async (req, res) => {
    const query = {
      senderUsername: req.params.senderUsername,
      recipientUsername: req.params.username,
    };

    const messages = await Messages.find(query).exec();

    res.json(messages);
  });

CodePudding user response:

Ok, so I managed to find a work around, created another query only this time the senderUser value will be the recipient username and recipientUsername value as the senderUsername :

  const query2 = {
    senderUsername: req.params.username,
    recipientUsername: req.params.senderUsername,
  };

Find with both quires while using $or:[query,query2].

the following example worked:

usersRoute
.route("/messages/thread/:username/:senderUsername")
.get(async (req, res) => {
  const query = {
    senderUsername: req.params.senderUsername,
    recipientUsername: req.params.username,
  };
  const query2 = {
    senderUsername: req.params.username,
    recipientUsername: req.params.senderUsername,
  };

  const messages = await Messages.find({$or:[query,query2]}).exec();

  console.log(messages);
  res.json(messages);
});

Could there be a better way to do it? I would really like to understand this better.

Thank you @Paweł Antyporowicz for the help :)

  • Related