0

I have done all your suggestions with some edits as per the response requirements and it is now working fine.Now the problem I am getting is with the like buttons that comes associated with the posts.I tried to recognize them with data-id attributes but everytime I click a particular button It's updating only in the 1 st P tag likes count.In the database also it affects only that 1st post besides using data-id to distinguish.I am not sure about my usage of data-id because this is the 1st time I am trying it.Please correct me with it,if wrong and help me associate the update likescount action with each of the looped button.I will update my code sample along with the response I get on my console.Please help me with it.

log on the console

(3) [{…}, {…}, {…}]0: {_id: "5b2673ed3e6a8e0c749b4c32", body: "kjhdishduishduihsduishduishdui shdishduihsuidsuids…opdksaodkjsa ↵dskjdiosajd ↵dsjadoisad ↵dsaoijdisa", author: "5b206e07e850480d50861f75", title: "simple post to test likes", __v: 0, …}1: {_id: "5b2073b7517e2b1760ffbbfd", body: "Quisque velit nisi, pretium ut lacinia in, element…da. Cras ultricies ligula sed magna dictum porta.", author: "5b206e07e850480d50861f75", title: "nodejs", __v: 0, …}2: {_id: "5b2073ad517e2b1760ffbbfc", body: "Quisque velit nisi, pretium ut lacinia in, element…da. Cras ultricies ligula sed magna dictum porta.", author: "5b206e07e850480d50861f75", title: "test", __v: 0, …}

main.js

$('.likeicon').on('click',() => {
     var id = $('.likeicon').attr('data-id');
    $.ajax({
      url:'/forum/addlikes/'+id,
      method:"POST"
    });
  });
  refresh();
});

function refresh(){
  $.ajax({
   url: "/forum/getlikes/",
   contentType: "application/json",
   method: "GET",
   success: function(response) {
     // console.log(response);
     $.each(response, function(index) {
  // console.log(response[index].likes);
  $(".likes-" + response[index]._id).first().html( response[index].likes );
});
   setTimeout(refresh, 500);
 }
});
}

index.pug

    extends layout

block content


  h1 #{title}
  ul.list-group
    each post, i in posts
      li.list-group-item
        a(href="/forum/"+post._id+"?"+post.author)= post.title
        div #{post.body}
        button(data-id=post._id class='likeicon' value=post._id)  LIKE
        p(class='likes-'+post._id)

post_routes.js

router.get('/getlikes/',(req,res) => {
  Post.find({},(err, posts) => {
    if(err){
      console.log(err);
    } else {
      posts = posts.slice(0).reverse();
      res.send(posts);
    }
  });
})

router.post('/addlikes/:id',(req,res) => {
  Post.findById(req.params.id,(err,post) => {
    if(err) throw err;
    else{
      post.likes+=1;
      post.save((err) =>{
        if(err) throw err;
        else{
          console.log(post.likes);
        }
      });
    }
  });

});

Please help me with this alone.I am almost done.Thanks in advance.

mariappan .gameo
  • 171
  • 1
  • 1
  • 15
  • the endpoint that returns the likes should not return html, but json with only the likes value. when received replace only the element.innertHTML manually. It looks like you want to add one more endpoint and use that instead. – ippi Jun 17 '18 at 13:09
  • Thanks a lot.I done as per your suggestion and it's working fine.You saved my life.I will be gratful to this community. – mariappan .gameo Jun 17 '18 at 13:44
  • It was working fine for the first time.But all of a sudden I am getting this error.Could someone help me with it. – mariappan .gameo Jun 17 '18 at 14:26
  • events.js:160 throw er; // Unhandled 'error' event ^ CastError: Cast to ObjectId failed for value "undefined" at path "_id" for model "posts" at MongooseError.CastError – mariappan .gameo Jun 17 '18 at 14:28
  • i think that may indicate req.parama.id was undefined, check it before you use it. also findById will probably make post undefined if it doesnt find an id but I think its unrelated to your error – ippi Jun 17 '18 at 14:42
  • And one more problem the likes count is showing up in only the topmost post ,the posts with the links,button in the pug view are showing up exactly as per the loop but why the p tag alone is not refreshing in all the other. – mariappan .gameo Jun 17 '18 at 14:50
  • I think its time to update your question with new code. too many guesses. it probably has to do with how you select and iterate over elements – ippi Jun 17 '18 at 14:52
  • Ok let me update it – mariappan .gameo Jun 17 '18 at 14:55
  • I have updated my code,I hope it will be clear now.Please help me how to make the same likes count increase functionality to all looped posts. – mariappan .gameo Jun 17 '18 at 15:03

1 Answers1

0

If you keep "spamming" requests, some will be slower than 500, meaning that soon you will have requests running at the same time. I would change your refresh to only send a new request after a successful response.

function refresh() {
  $.ajax({
    url: "/getlikes",
    contentType: "application/json",
    method: "GET",
    success: function(response) {
      setTimeout(refresh, 500);
    }
  });
}

Oh, and jquery actually has a shortcut for that:

$.getJSON( "/getlikes" + id, function( response ) {
    setTimeout(refresh, 500);
});

In HTML, always make sure your id's are unique. it's only working now because the browser is being nice to you. document.getElementById('likes') this will always find the same single tag, even though you have many. You can use $('.cssSelector') to find many elements with jquery.

You could add your id to a class like: p(class='likes-' + post._id) but it's popular to use data-attributes to attach your data to an element. How to get the data-id attribute? CSS-classes has a different purpose after all.

and return all your likes with one json:

[ { id: "id1", likes: 15 }, { id: "id2", likes: 15 }];

Then when you receive them :

// not really sure how the response looks like, but something like this perhaps?

response.data.forEach( function( item ){
    $(".likes-" + item.id).first().html( item.likes ); // .html() is how jQuery does .innerHtml
});

And Im guessing here as well, but maybe like this on the server side:

router.get('/getlikes',(req,res) => {
  Post
    .find({})
    .select("_id likes")
    .sort({likes:-1})
    .limit(5)  // sort by likes and add limit for a "top5"
    .lean()
    .exec(err,posts) => {
      if(err) throw err;
      else {
        res.send( posts ) ;
      }
    }
  })
})

Lot's of guesswork here since I'm unable to test it out at the moment. sorry for that. But it should be close, and maybe it at least can give you some ideas.

ippi
  • 9,857
  • 2
  • 39
  • 50
  • Sorry for disturbing you again,I've almost done with it.I am trying on my own too.But if you feel like suggesting the way to do it by looking the above code again when you are free,please help me with it. – mariappan .gameo Jun 17 '18 at 17:45
  • How to associate likes button looped through with action,tried with data-id attributes,but couldn't figure out exactly.Could you please tell me how to do it?Please have a look at the edited code when you are free. – mariappan .gameo Jun 17 '18 at 18:56
  • Thank you @ippi I had a look at data-id in detail and figured out what's wrong with it.Now problem is fixed. – mariappan .gameo Jun 17 '18 at 20:01