2

I used this method because I am storing an array of classified messages, I would like to vividly understand why it doesn't update.

Here's the db.js:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ObjectId = mongoose.Types.ObjectId;

const usersessionSchema = new Schema({
  fb_id: String,
  fb_name: String,
  fb_profpic: String,
  message_body: [
    {
      message: String,
      message_type: String,
      timestamp: String
    }
  ],
  admin: Boolean,
  branch: String
});

const model = (prefix) => {
    prefix = prefix || '';
    console.log(prefix);
    if (prefix.length > 0) {
        return mongoose.model(prefix + "-usersessions", usersessionSchema);
    } else {
        return new Error('Undefined collection prefix!');
    }
}
/** Push message into message body*/
    module.exports.pushsession =
        async(model, id, data) => {
            return new Promise((resolve, reject) => {
                console.log(data);
                model.findOneAndUpdate({fb_id: id}, {$push: {data}},{safe: true})
                    .then(res => {
                        console.log(res);
                        /
                        resolve(res);
                    })
                    .catch(err => {
                        reject(err);
                        console.log(err);
                        throw err;
                    });
        });
    }

Here's the controller.js:

/** Push usersession message  */
module.exports.pushsession =
    async(req, res, next) => {
        try {
            //jwt.validateToken(req);
            var en = "en";
            var dateEn = moment().locale(en);

            format = "MM/DD/YYYY h:mm:ss A"; //h:mm:ss.SSS if you want miliseconds

            var datetime_now = dateEn.format(format);

            console.log(datetime_now);

            var request = {

                    message_body: {
                        message: req.body.message,
                        message_type: req.body.message_type,
                        timestamp: datetime_now
                    }
            };

            const model = usersessionDB(req.query['client']);
            const id = req.body.fb_id;
            const result = await usersessionDB.pushsession(model, id, request);
            if (result) {
                response.success(res, next, result, 200, response.HTTP_STATUS_CODES.ok);
            } else {
                response.failure(res, next, {
                    message: 'ID does not exist'
                }, 404, response.HTTP_STATUS_CODES.not_found);
            }
        } catch (err) {
            response.failure(res, next, err, 500, response.HTTP_STATUS_CODES.internal_server_error);
        }
    }

Here's the route.js:

const controller = require('../controller/usersession-controller');

module.exports =
    (server) => {
        server.post('/api/session', controller.create);
        server.get('/api/session', controller.list);
        server.get('/api/session/:id', controller.get);
        server.put('/api/session/:id', controller.update);
        server.del('/api/session/:id', controller.delete);
        server.put('/api/pushsession', controller.pushsession);
    }

Visually, if you run this using postman, you can see that it display the one I want to search and update

Result of the postman

What I want to happen is to insert another set of array inside that message_body

Data I've inserting

My desired output

This code is working without that promise something, but in my project it is needed so I can't remove that thing.

Quer
  • 405
  • 7
  • 16

2 Answers2

1

So, based on :

This code is working without that promise something

i can point a thing or two,

in db.js

 module.exports.pushsession =
        async(model, id, data) => {
            return new Promise((resolve, reject) => {

you don't need async since you're returning a promise so replace this

async(model, id, data) => {

with

(model, id, data) => {

and since you're returning a promise and removed async , you don't need the await on the other side ( controller.js ), so this

 const result = await usersessionDB.pushsession(model, id, request);
            if (result) {
                response.success(res, next, result, 200, response.HTTP_STATUS_CODES.ok);
            } else {

should be

usersessionDB.pushsession(model, id, request).then(
    (result) => { // when resolved
        response.success(res, next, result, 200, response.HTTP_STATUS_CODES.ok);
    }, 
    (err) => { // when rejected
        response.failure(res, next, {
                    message: 'ID does not exist'
                }, 404, response.HTTP_STATUS_CODES.not_found);
    });

this is a comparison between async/await and promises : Javascript Promises vs Async Await. Difference?

and here's some good examples of using promises : https://medium.com/dev-bits/writing-neat-asynchronous-node-js-code-with-promises-32ed3a4fd098

i think your $push is ok but you already said

This code is working without that promise something

i hope this helps and Good luck :)

Taki
  • 17,320
  • 4
  • 26
  • 47
  • Taki! :D I've tried removing the await and async, but I still had the same results? – Quer Mar 16 '18 at 07:47
0

I tried cleaning my code

here's the controller.js:

/** Push usersession message  */
module.exports.pushsession =
   async (req, res, next) => {
        try {
            //jwt.validateToken(req);
            var en = "en";
            var dateEn = moment().locale(en);

            format = "MM/DD/YYYY h:mm:ss A"; //h:mm:ss.SSS if you want miliseconds

            var datetime_now = dateEn.format(format);

            console.log(datetime_now);

            var data = { 

                    message: req.body.message, 
                    message_type: req.body.message_type,
                    timestamp: datetime_now

            };


            const model = usersessionDB(req.query['client']);
            const id = req.body.fb_id;
            console.log(id);
            const result = await usersessionDB.pushsession(model, id, data).then(
                (result) => { // when resolved
                    response.success(res, next, result, 200, response.HTTP_STATUS_CODES.ok);
                }, 
                (err) => { // when rejected
                    response.failure(res, next, {
                                message: 'ID does not exist'
                            }, 404, response.HTTP_STATUS_CODES.not_found);
                });
        } catch (err) {
            response.failure(res, next, err, 500, response.HTTP_STATUS_CODES.internal_server_error);
        }
    }

Here's the db.js:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ObjectId = mongoose.Types.ObjectId;

const usersessionSchema = new Schema({
  fb_id: String,
  fb_name: String,
  fb_profpic: String,
  message_body:[{
      message: String,
      message_type: String,
      timestamp: String
  }],
  admin: Boolean,
  branch: String
});
/** Push message into message body*/
module.exports.pushsession =
async(model, id, data) => {
    console.log(data);
    return new Promise((resolve, reject) => {
        model.findOneAndUpdate({fb_id: id}, { $push: { message_body: data }})
        .then(res => {
            console.log(res);
            resolve(res);
        })
        .catch(err => {
            reject(err);
            console.log(err);
            throw err;
        });
    });
}

Out of the blue after I tried to replace $push with $set then again I replace it with $push, it worked. I don't if there's a difference, or I miss something, feel free to point it out.

Quer
  • 405
  • 7
  • 16
  • could be because of the `/` you had in the `.then` between `console.log()` and `resolve()` , and it's better to precise the key you want to update in the `$push` (`message_body : ...`) instead of passing it in an object, and you're using the promises the right way in your controller with `.then()` instead of just `result = await ...` as i mentioned in my answer :) , but because you said the code is working without the `promise` i didn't look at the other parts , anyways, i'm glad you got this working :) ( just mark the question as answered and one of the answers as accepted ) – Taki Mar 16 '18 at 16:03