I'm trying to build a message board to teach myself JavaScript. I'm working with:
- nodejs
- angularjs
- express
- mysql
I have a view /board
that uses the following route (and corresponding sqlize query) to fetch data for displaying the "board index":
router.get('/api/board/fetch', function(req, res) {
if(req.session.key) {
dbconn.threads.findAll({
order: 'id DESC',
include: [{
model: dbconn.users,
attributes: ['id', 'username', 'first_name']
}]
}).then(function(threads) {
return res.send({ success: true, threads: threads }); // return all threads found in table
});
} else {
return res.send({ success: false, msg: 'Error: Posts' })
}
});
The above example simply fetched the threads with some associated model data to display a summary index. Now, in order to also show the current "post count" within a specific thread, I modified the sqlize to:
router.get('/api/board/fetch', function(req, res) {
if(req.session.key) {
dbconn.threads.findAll({
order: 'threads.id DESC',
group: ['threads.id', 'replies.id'],
raw: true,
include: [{
model: dbconn.users,
attributes: ['id', 'username', 'first_name'],
}, {
model: dbconn.replies,
attributes: [[sequelize.fn('COUNT', 'id'), 'replyCount']],
}]
}).then(function(threads) {
return res.send({ success: true, threads: threads }); // return all threads found in table
});
} else {
return res.send({ success: false, msg: 'Error: Posts' })
}
});
I pieced this together using this SO question and this GH issue, but rather than having output of:
Thread Title | # Replies
It lists the same data 5 times with a "# Replies" of 0 for all of them. What I believe is happening:
- I am not accurately counting all
replies.id
wherethreadId
= 'x' - I have not correctly implemented the sequelize.fn("COUNT") ... syntax
For better context (hopefully), I have the following in my controller:
board.fetch().then(function(data) {
$scope.thread = data
console.log("data obj -> ", data)
})
Which uses the following from my service.js:
fetch : function() {
return $http.get('/api/board/fetch').then(function(response) {
return response.data
})
},
In the browser, the object understandably has five objects in a threads
array, all containing the same data (makes sense from the sqlize query) and replies.replyCount: 1
.
I apologize for the terrible code, naming conventions, and if this is answered elsewhere. I've spent a while today trying to figure this out but have been limited in my lack of understanding to search for the right question.
I can provide the model definitions if those are necessary; the post just felt very long already.
Update: Modified code per Shivam's observation and it now works as I need it to. Updated code below:
dbconn.threads.findAll({
order: 'threads.id DESC',
raw: true,
attributes: {
include: ['title', 'body', 'slug', 'createdAt', 'userId', [sequelize.fn('COUNT', 'replies.id'), 'replyCount']]
},
include: [{
model: dbconn.users,
}, {
model: dbconn.replies, attributes: [],
}],
group: ['threads.id', 'replies.threadId'],
}).then(function(threads) {
return res.send({ success: true, threads: threads }); // return all threads found in table
});
} else {
return res.send({ success: false, msg: 'Error: Posts' })
}