1

I am attempting to build a Vue.js App that synthesizes properties of AWS, MongoDB, and Express. I built an authentication page for the app using aws-amplify and aws-amplify-vue. After logging into the app, metadata containing the username for the logged in AWS user is passed into data object property this.name like so:

  async beforeCreate() {
    let name = await Auth.currentAuthenticatedUser()
    this.name = name.username
  }

this.name is then added to MongoDB via Axios:

    async addName() {
        let uri = 'http://localhost:4000/messages/add';
        await this.axios.post(uri, {
          name: this.name,
        })
        this.getMessage()
      } 

I also have a getName() method that I am using to retrieve that data from MongoDB:

    async getData () {
      let uri = 'http://localhost:4000/messages';
      this.axios.get(uri).then(response => {
        this.userData = response.data;
      });
    },

This method, however, returns data for ALL users. I want to reconfigure this method to ONLY return data for .currentAuthenticatedUser(). In my previous experience with Firebase, I would set up my .getData() method with something like:

let ref = db.collection('users')
let snapshot = await ref.where('user_id', '==', firebase.auth().currentUser.uid).get()

...in order to return currentUser information on the condition that 'user_id' in the collection matches the currently logged-in Firebase user.

To achieve this with MongoDB, I attempted to configure the above method like so:

    async getData () {
      let uri = 'http://localhost:4000/messages';
      let snapshot = await uri.where('name', '==', this.name);
      this.axios.get(snapshot).then(response => {
        this.userData = response.data;
      });
    },

My thought here was to try and return current user data by comparing 'name' in the MongoDB collection with the logged-in user stored in this.name...but I understand that this might not work because the .where() method is probably unique to Firebase. Any recommendations on how to configure this .getData() to return ONLY data associated with the currentAuthenticatedUser? Thanks!

EXPRESS ROUTES:

const express = require('express');
const postRoutes = express.Router();

// Require Post model in our routes module
let Post = require('./post.model');

// Defined store route
postRoutes.route('/add').post(function (req, res) {
  let post = new Post(req.body);
  post.save()
    .then(() => {
      res.status(200).json({'business': 'business in added successfully'});
    })
    .catch(() => {
      res.status(400).send("unable to save to database");
    });
});

// Defined get data(index or listing) route
postRoutes.route('/').get(function (req, res) {
    Post.find(function(err, posts){
    if(err){
      res.json(err);
    }
    else {
      res.json(posts);
    }
  });
});

module.exports = postRoutes;

1 Answer 1

1

It is not possible to apply a where clause to a uri AFAIK. What you should do is adding a where clause to the actual query you are making in your backend and, to do that, send the username you want to filter the query with through a query parameter like this: /messages?name=JohnDoe.

So basically if you are using a Node/Express backend, as you suggested, and using Mongoose as the ODM for MongoDB your request would probably be looking something like this:

const Users = require('../models/users.model');

Users.find({}, function (e, users) {
    if (e) {
        return res.status(500).json({
            'error': e
        })
    }

    res.status(200).json({
        'data': users
    });
})

What you should do is getting the username query parameter through req.query and add it to the options in the first parameter of the find function.

const Users = require('../models/users.model');

let params = {},
    name = req.query.name;

if (name) {
    params.name = name
}

Users.find(params, function (e, users) {
    if (e) {
        return res.status(500).json({
            'error': e
        })
    }

    res.status(200).json({
        'data': users.slice
    });
})

That way if you point to /messages?name=John you will get the users with "John" as their name.

Edit:

If your backend is configured in the following way

postRoutes.route('/').get(function (req, res) {
    Post.find(function(err, posts){
    if(err){
      res.json(err);
    }
    else {
      res.json(posts);
    }
  });
});

what you should do is get the query parameters from inside the get method

postRoutes.route('/').get(function (req, res) {
    let params = {},
        name = req.query.name

    if (name) {
       params.name = name
    }

    Post.find(params, function(err, posts){
    if(err){
      res.json(err);
    }
    else {
      res.json(posts);
    }
  });
});
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the feedback! Please see the Express Routes above that I added to my question. I am indeed using Mongoose, but my routes are set up a little different than the ones you posted. How can I still use req.query in an Express route setup like the one I am using?
It's pretty much the same thing, I'll add it now to my answer.
Excellent. I implemented that. As far as prompting the route to return username data, I attempted to configure the query paramater in getData() to look like this: http://localhost:4000/messages?username=${this.name} by passing in the targeted username into the URL, but this still did not work. Based on your answer regarding the query parameter, how can I configure the query parameter in the URL to send a request based on the authenticated user?
Perhaps because the name of your field in the db is name and not username. Try making it /messages?name=${this.name} and in the backend replace username with name. I just used username because it was descriptive and I didn't know what was the name of your field.
The trick was to pass in the authenticated name into the query parameter, and then configure the Express route to query that name, then respond with data based on that queried name
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.