Home > Software engineering >  node.js express only return elements related to the user
node.js express only return elements related to the user

Time:04-01

I want to only return the trades that belong to the currently logged in user. I store the user inside the header of each request. In each trade I have stored the creator.

My GET method looks like this:

exports.getTrades = (req, res, next) => {
  const tradeQuery = Trade.find();
  let fetchTrades;

  tradeQuery
    .then((trades) => {
      fetchTrades = trades.filter((t) => t.creator._id === req.userData.userId); <---
      return;
    })
    .then((count) => {
      res.status(200).json({
        message: "Trades fetched successfully!",
        trades: fetchTrades,
      });
    })
    .catch((error) => {
      res.status(500).json({
        message: "Fetching trades failed!",
      });
    });
};

I tried console logging the two attributes i compare inside my filter manually, and there actually are trades where both are the same. However fetchTrades remains empty.

I really would appreciate some ideas.

Here are the two models:

user.js:

const mongoose = require("mongoose");
const uniqueValidator = require("mongoose-unique-validator");

const userSchema = mongoose.Schema({
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true },
});

userSchema.plugin(uniqueValidator);

module.exports = mongoose.model("User", userSchema);

trade.js:

const mongoose = require("mongoose");

const tradeSchema = mongoose.Schema({
  pair: { type: String, required: true },
  type: { type: String, required: true },
  resultAmount: { type: Number, required: true },
  date: { type: Date, required: true },
  time: { type: Date, required: true },
  creator: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User",
    required: true,
  },
  leverage: { type: Number },
  entry: { type: Number },
  exit: { type: Number },
  lessonLearned: { type: String },
});

module.exports = mongoose.model("Trade", tradeSchema);

EDIT: thats how the trade looks like:

{
  _id: 6245bf565043276fb456cb6a,
  pair: 'BTCUSD',
  type: 'long',
  resultAmount: 239,
  time: 2022-03-22T23:00:00.000Z,
  date: 2022-03-31T14:48:28.916Z,
  creator: 62409c68e17cae2d68a99b3b,
  leverage: 20,
  entry: 1.2321,
  exit: 1.2377,
  lessonLearned: 'I was good man',
  __v: 0
}

EDIT2: Thanks to @vicki. I had to use "==" instead of "===" inside my filter function.

CodePudding user response:

There is an error in your usage of filter function. You are returning nothing instead of matched entries.

tradeQuery
.then((trades) => {
  fetchTrades = trades.filter((t) => t.creator._id === req.userData.userId);
  return;
})

This is your usage. Change it as

tradeQuery
.then((trades) => {
  fetchTrades = trades.filter((t) => return t.creator._id === req.userData.userId);  
})

This should possibly fix your issue. Adding a js snippet

let trades = [{
    "id": 1,
  "name": 'asd'
},
{
    "id": 2,
  "name": 'qwe'
},
{
    "id": 1,
  "name": 'efg'
}]

let fetchTrades

{
    fetchTrades = trades.filter((t) => {
                       t.id === 1;
                       return
                  })
}

console.log('improper usage',fetchTrades)

{
    fetchTrades = trades.filter((t) => {
                      return t.id === 1;
                  })
}

console.log('Proper usage',fetchTrades)

EDIT: There may be issues when you compare ObjectIDs, using === will type check as well. So, it is advisable to use t.creator._id.equals(req.userData.userId) or ==. As @ApoorvaChikara pointed out, don't use the return statement inside filter function.

CodePudding user response:

what helped me accomplish the filtering is the mongoose find() method. you can pass in a field which you want to match with an userid. in order to do this i implemented a repository file which exports all the db query functions. in my case i want to fetch all periods from a specific user.

my period.repo.ts looks like this:

// period.repo.ts
import Period from '../models/period.model';
 
class PeriodRepository {
  findAllFromUser(userId: String) {
    return Period.find({ userId: userId });
  }
   
}
    
export default new PeriodRepository();

then in my service file which contains my business logic for the backend i import and use the repo file like this:

// period.service.ts
import PeriodRepository from './period.repository';

getCycle(req, res) {
    let cycleLength = 1;
    let lastPeriod;
    PeriodRepository.findAllFromUser(req.params.userId)
      .then((periods) => {
        cycleLength = periodHelper.calcAverageCycleLength(periods, 0);
        if (lastPeriod?.endDate) {
          return res.status(200).json({
            message: 'predictions fetched',
            cycleLength: cycleLength,
          });
        } else {
          return res.status(200).json({
            message: 'period is active',
            remainingDaysPeriod: 0,
            remainingDaysOvaluation: 0,
          });
        }
      })
      .catch((error) => {
        return res.status(500).json({
          message: 'fetching periods failed',
        });
      });
  }

this way i only query the documents which belong to the selected user.

  • Related