How to make comment render immediately after adding it?

I have two function which is create post and create answer for the post.

For the create post function, the post will render immediate on the web page. But when i add an answer for it, i need to refresh the web page to make the answer render on the web page.

Actually both function are the same, why the post will render after posting it but the answer won’t?

Create Post function:

    postQuestion(attrs)
        const post = this.store.createRecord('post', {
            title: attrs.title,
            description: attrs.description,
            file: attrs.file,
        });
        post.save();
     }

Create Answer function:

    postAnswer(attrs){
        let post = this.store.peekRecord('post',this.model.post.id)
        let answer = this.store.createRecord('answer', {
            post: post,
            answer:attrs.answer,
        });
        answer.save();
    },

Create Post Route

     model() {
           return this.store.findAll('post');  
    }

Create answer route

  model(params) {
         let answer =  await this.get('store').query('answer', {filter: { post: params.id }});
         return answer;
   }

Both template render like this:

 {{#each model as |post|}}
       {{post.title}}
  {{/each}}

Hi!

I am not an expert, but you may not need an await operator on your answer route.

1 Like

I think you’re running into a common tripping point in the Ember Data methods (I had a lot of confusion around this when I was learning Ember Data too)…

In short, when you call findAll as you are in your post route, it returns a live updating model array which will continually be refreshed if new records enter the store.

However when you use query as you are in the answer route, it returns a static array of results. At first this may seem a little incongruous and annoying (or at least it did for me when I was working through learning all of this) however it makes sense if you think about what the methods are for. The findAll method is literally that, find “all”, so it seems natural to update the results if new records come into play. In this case the server and the client can agree on what “all” is and the server doesn’t need any special knowledge that the client can’t have, it’s just “all”. So the server returns “all” and the client displays “all” the records that it has, including new records that get created on the client and saved.

A query on the other hand is different. When you submit a query to the server, the server sends back the results at a single moment in time so if records are created, updated or deleted that query is invalidated. However the server does have special knowledge in this case, the client doesn’t know that any of that has happened, nor does it know all of the filter criteria/logic, so it must refetch to get the newest results, which again will only be a snapshot. Obviously if you have a server push situation the server could notify the client of query results being updated via websockets or whatever, but in a RESTful world this isn’t possible. So it would be unnatural for a query result from the store to update “live” because the client is not the source of truth about what makes up results for that query.

So what can you do about it? There are a few options. Other than the fancy websocket solution you could refresh the route model using an action or instead of returning the query results from the model you could still make the query but return findAll('answer') and then filter that down to what you want using Ember computed in the controller or a component.

1 Like

Hi, @dknutsen. I’ve created a computed property like this:

postAns: computed('dateSortedAns',function() {
        // let ans = this.get('dateSortedAns').filterBy('post',this.model.post.id);
        var postId = this.model.post.id;
        return this.dateSortedAns.forEach(function(ans) {
            if (ans.post.get('id') == postId)
               // console.log(ans)
                return ans;
        })
    }),

I’m able to get the answer by using console.log(ans). But when I try to use {{this.postAns}} at template, it return nothing. Is there any wrong?

you’re returning the results of forEach which doesn’t return anything. Perhaps you meant to use map or filter?

In fact the filterBy line that you have commented out looks about right, except I think you’d want to do filterBy('post.id', this.model.post.id) (your code as written would be comparing a post model to a post id which would always return false).

By using this way had solve the issues. Thanks a lot for your information @dknutsen. Now i have know how to use in between query and findAll.