Kay
Kay

Reputation: 19700

How to implement a follow system, return a list of followers and following users

In my application there are 4 features I need to implement:

  1. A user can follow another user.
  2. A user can unfollow another user.
  3. A user can see a list of all of their followers.
  4. A user can see a list of all whom they are following.

I believe I have implemented 1. and 2. correctly. I created a follow schema as you can see below in my follow.model and I have created follow.controller with two methods, to store (follow) and destroy (unfollow).

Now I want to to implement 3. and 4. I created two arrays in the user.model schema, one for following and one for followers. When I return the user in my user.controller, how do I populate the following and followers array? At the moment they are empty.

follow.model.js

var mongoose = require('mongoose'),
Schema   = mongoose.Schema;

var FollowSchema = new Schema({

    follower: {
        type: Schema.Types.ObjectId,
        ref: 'User'
    },
    followee: {
        type: Schema.Types.ObjectId,
        ref: 'User'
    }
},
{
    timestamps: {createdAt: 'created_at', updatedAt: 'updated_at'}
});

module.exports = mongoose.model('Follow', FollowSchema);

follow.controller.js

'use strict';

const User = require('../models/user.model');
const Follow = require('../models/follow.model');


class FollowController {

    constructor() {

    }


    store(req, res) {

        let follower = req.body.follower;
        let followee = req.params.id;

        let follow = new Follow({
            follower: follower,
            followee: followee,
        });

        follow.save(function (err) {

            if (err) {
                return res.status(404).json({
                    succes: false,
                    status: 404,
                    data: {},
                    message: "There was an error trying follow the user."
                });
            }

            return res.status(200).json({

                success: true,
                status: 200,
                data: follow,
                message: 'Successfully followed user'

            });
        });
    }
    destroy(req, res) {

        let follower = req.params.followerid;
        let followee = req.params.id;

        Follow.remove({ 'follower': follower, 'followee': followee }, (err, result) => {

            if (err) {
                return res.status(404).json({
                    success: false,
                    status: 404,
                    data: {},
                    message: "Error removing record"
                });
            }


            return res.status(201).json({
                success: true,
                status: 201,
                data: {},
                message: "Successfully unfollowed user"
            })

        });
    }

}

module.exports = FollowController;

user.model.js

let UserSchema = new Schema({

        email: {
            address: {
                type: String,
                lowercase: true,
                //unique: true,

            },
            token: String,
            verified: {
                type: Boolean,
                default: false,
            },
        },
        password: {
            type: String,
        },

        following: [{
            type: Schema.Types.ObjectId, ref: 'Follow'
        }],
        followers: [{
            type: Schema.Types.ObjectId, ref: 'Follow'
        }],


    {
        timestamps: {createdAt: 'created_at', updatedAt: 'updated_at'}
    });

user.controller.js

  show(req, res) {

        let id = req.params.id;

          User.findOne({ '_id': id },
         function (err, user) {

            if (err) {
                return res.json(err);
            }

            return res.json(user);

        });
    }

Upvotes: 1

Views: 2848

Answers (1)

TGrif
TGrif

Reputation: 5941

You just need to populate these fields:

User.findOne({ '_id': id }, (err, user) => {
  if (err) return res.json(err);
  return res.json(user);
}).populate([
  { path: 'following' },
  { path: 'followers' }
]);

Upvotes: 2

Related Questions