0

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 where threadId = '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' })
    }
omnomagonz
  • 1
  • 1
  • 3
  • Looking along with the GH issue, You should count on the parent model and not in the included model. Having count in include would give you a count 1, everywhere. – Shivam Jul 21 '17 at 06:54
  • So I circled back and modified the code to include that fix. Now seems to work ok. Thank you for pointing out that oversight on my part! – omnomagonz Jul 21 '17 at 15:03

0 Answers0