Как получить доступ / вернуть значения из документа mongo с помощью запроса mongoose и async-await / Promise? - PullRequest
0 голосов
/ 03 января 2019

Я использовал mongoDB, но я новичок в Node.js и mongoose, и я пытаюсь понять, как использовать mongoose с async-await / Promises. Я создаю приложение React / Node с веб-сокетами (socket.io), где пользователи могут создать учетную запись и войти в систему, если у них уже есть учетная запись. Мне удалось успешно создать и выполнить запрос mongo / mogoose, но у меня возникают проблемы с использованием документа, как только он у меня есть. Вот как выглядит мой код:

const profileRoute = (action, io) => {
    switch (action.cmd) {
        case 'LOGIN':
            getProfile(action.email)
                .then(profile => {
                    console.log('profile: ', profile)     // prints the mongo document properly.
                    console.log('email: ', profile.email) // email: undefined
                    io.emit('action', {
                        type: PROFILE_LOGIN,
                        email: profile.email,
                        name: profile.name,
                    });
                .catch(err => {console.log(err)});
            break;
        default:
            break;
    }
};

И вот как выглядит getProfile ():

export const getProfile = async (email) => {
    const tempPromise = collection.findOne({ email }).exec();
    try {
        return await tempPromise;
    } catch (err) {
        console.log(err);
        return {};
    } 
};

Я также пытался объяснить "getProfile ()", так как async-await здесь не сильно поможет (просто хотел попробовать что-то маленькое, чтобы начать):

export const getProfile = (email) => {
    return collection.findOne({ email }).exec();
};

Но в любом случае я пытаюсь при печати "profile.email" он не определен, и мой результат из

io.emit('action', {
    type: PROFILE_LOGIN,
    email: profile.email,
    name: profile.name,
});

является:

{
    type: PROFILE_LOGIN,
}

но если я сделаю это:

io.emit('action', {
    type: PROFILE_LOGIN,
    profile: profile,
});

результат:

{
    type: PROFILE_LOGIN,
    profile: {correct mongo document},
}

Но мне нужно / нужно только несколько значений из монго-документа.

Кроме того, если есть лучший способ переписать "profileRoute ()" (я знаю, что этот вопрос не совсем об этом), используя async-await, я открыт для предложений.

РЕДАКТИРОВАТЬ: Была опечатка, когда я первоначально написал этот вопрос. Изменено:

{
    type: PROFILE_LOGIN,
    profile: [correct mongo document],
}

Это более точно отражает отдачу от ".findOne ()":

{
    type: PROFILE_LOGIN,
    profile: {correct mongo document},
}

Ответы [ 2 ]

0 голосов
/ 04 января 2019
const profileRoute = async (action, io) => {
  switch (action.cmd) {
    case 'LOGIN':
      try {
        const profile = await getProfile(action.email);
        if (!profile) {
          throw new Error(`Profile with email ${action.email} not found`);
        }
        io.emit('action', {
          type: PROFILE_LOGIN,
          email: profile.email,
          name: profile.name
        });
      } catch (e) {
        console.log(e);
      }
      break;
    default:
      break;
  }
};

И ваш getProfile() код будет просто:

export const getProfile = email => {
  return collection.findOne({ email }).exec();
};
0 голосов
/ 03 января 2019
export const getProfile = async (email) => {
    const tempPromise = collection.findOne({ email }).exec();
    try {
        return await tempPromise;
    } catch (err) {
        console.log(err);
        return {};
    }  };

Вы должны добавить await перед collection.findOne И если вы хотите получить только объект json, вы можете добавить lean () в конце запроса mongoose, как этот.

export const getProfile = async (email) => {
    const tempPromise = await collection.findOne({ email }).lean().exec();
    try {
        return await tempPromise;
    } catch (err) {
        console.log(err);
        return {};
    } 
};
...