0

I am having a bit of trouble getting my current project to work at the moment... I know I am not following some of the best practices when it comes to structure, but this is meant solely as a test of functionality until I can get it working and then I will properly build it out.

I'm working on construction a simple forum with boards, posts, and then comments. I am basing it off of this thinkster.io tutorial, https://thinkster.io/mean-stack-tutorial#opening-rest-routes.

The boards and posts I have functioning, but adding comments is another story. I have tried adding a new Comment schema and defining some server side routes to allow me to get and post comments, but this did not work out. Now my strategy is to just put the comments in my mongoose postSchema and then hide them and the comment form or inject the html with angular when a User clicks the view comments button. This isn't working either though because my submit does not update the view or the database. This is currently what I am working with.

app.js

(function() {
angular.module('test', ['ui.router', 'ngMaterial'])
.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
    $stateProvider
        .state('home', {
            url: '/home',
            templateUrl: '/views/home/home.html',
            controller: 'MainController',
            resolve: {
                boardPromise: ['boards', function (boards) {
                    return boards.getAll();
                }]
            }
        })

        .state('boards', {
            url: '/boards/{id}',
            templateUrl: '/views/posts/posts.html',
            controller: 'PostsController',
            resolve: {
                board: ['$stateParams', 'boards', function ($stateParams, boards) {
                    return boards.get($stateParams.id);
                }]
            }
        });



    $urlRouterProvider.otherwise('home');
}]);
}());

Then My controllers are as follows:

Main Controller

(function () {
angular.module('test')
.controller('MainController', ['$scope', 'boards', function($scope, boards) {
    $scope.boards = boards.boards;

    $scope.addBoard = function() {
        if ($scope.title === '') {
            return;
        }
        boards.create({
            title: $scope.title,
            description: $scope.description,
        });

        $scope.title = '';
        $scope.description = '';
    };
}]);
}());

Posts Controller

(function() {
'use strict';

angular.module('test')
.controller('PostsController', ['$scope', 'boards', 'board', function ($scope,                  boards, board) {
    $scope.board = board;

    $scope.addPost = function() {
        if ($scope.body === '') {
            return;
        }

        boards.addPost(board._id, {
            body: $scope.body,
            author: 'user',
        }).success(function (post) {
            $scope.board.posts.push(post);
        });
        $scope.body = '';
    };

    $scope.addComment = function() {
        if ($scope.commentts === '') {
            return;
        }

        boards.addComment(board._id, {
            comments: $scope.comments,
            author: 'user',
        }).success(function (comment) {
            $scope.board.posts.comments.push(comment);
        })
        $scope.comments = ''
    };
}]);
}());

The service handling my $http,

(function() {
'use strict';

angular.module('test')
.factory('boards', [ '$http', function($http) {
    var o = {
        boards: []
    };

    o.getAll = function() {
        return $http.get('/boards').success(function (data) {
            angular.copy(data, o.boards);
        });
    };

    o.create = function(board) {
        return $http.post('/boards', board).success(function (data) {
            o.boards.push(data);
        });
    };

    o.get = function(id) {
        return $http.get('/boards/' + id).then(function (res) {
            return res.data;
        });
    };

    o.addPost = function (id, post) {
        return $http.post('/boards/' + id + '/posts', post);
    };

    o.addComment = function (id, comment) {
        return $http.post('/boards/' + id + '/posts', comment);
    };


    return o;
}]);
}());

This is the pertinent part of my backend:

'use strict';

var mongoose = require('mongoose'),
Board = mongoose.model('Board'),
Post = mongoose.model('Post');

module.exports = function (app) {

app.get('/boards', function (req, res, next) {
    Board.find(function (err, boards) {
        if (err) {
            return next(err);
        }

        res.json(boards);
    });
});

app.post('/boards', function (req, res, next) {
    var board = new Board(req.body);

    board.save( function (err, board) {
        if (err) {
            return next(err);
        }

        res.json(board);
    });
});

app.param('board', function (req, res, next, id) {
    var query = Board.findById(id);

    query.exec(function (err, board) {
        if (err) {
            return next(err);
        }

        if (!board) {
            return next(new Error('can\'t find the boards'));
        }

        req.board = board;
        return next();
    });
});

app.param('post', function (req, res, next, id) {
    var query = Post.findById(id);

    query.exec = function (err, post) {
        if (err) {
            return next(err);
        }

        if (!post) {
            return next(new Error('can\'t find the post'));
        }

        req.post = post;
        return next();
    };
});

app.param('comment', function (req, res, next, id) {
    var query = Comment.findById(id);

    query.exec = function (err, comment) {
        if (err){
            return next(err);
        }

        if (!comment) {
            return next(new Error('can\'t find the comment'));
        }

        req.comment = comment;
        return next();
    };
});

app.get('/boards/:board', function (req, res, next) {
    req.board.populate('posts', 'comments', function (err, board) {
        if (err) {
            return next(err);
        }
        res.json(board);
    });
});

app.post('/boards/:board/posts', function (req, res, next) {
    var post = new Post(req.body);
    post.board = req.board;

    post.save(function (err, post) {
        if (err) {
            return next(err);
        }

        req.board.posts.push(post);
        req.board.save(function (err, board) {
            if (err) {
                return next(err);
            }

            res.json(post);
        });
    });
});

};

And the corresponding schemas:

The Board schema:

'use strict';

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

var boardSchema = new Schema({
  title: String,
  description: String,
  posts: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Post'
  }]
});

mongoose.model('Board', boardSchema);

and the Post schema:

'use strict';

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

var postSchema = new Schema({
  body: String,
  author: String,
  comments: {
    type: String,
  },
  board: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Board'
  },
});

mongoose.model('Post', postSchema);

Any help is appreciated. I am fairly new to using angular and the MEAN stack in general, but I am really looking to get better. Any information that you guys might be able to give me will surely improve my understanding. Thank you so much! :)

gnerkus
  • 11,357
  • 6
  • 47
  • 71
bashkir
  • 11
  • 4

1 Answers1

0

The comments field of your Post schema is defined as a single string. This means that each new comment overwrites the previous one. It should be defined as an array of strings instead:

Post schema

var postSchema = new Schema({
  body: String,
  author: String,
  comments: [{
    type: String,
  }],
  board: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Board'
  },
});

mongoose.model('Post', postSchema);
gnerkus
  • 11,357
  • 6
  • 47
  • 71