Can LiveView push_event send only the latest event

Thanks to the awesome community we have here.

I have created a VueJs component using phx-hook. I have also used phx-update=“ignore” on the same component. The idea is to handle the user interaction using vuejs and exchange data using liveview. It works fine but there is an important issue.
When i am initialising the component in the update method of the live_component i do this

    {:ok,
     push_event(socket, "table_data_init", %{
       columns: cols,
       rows: rs,
       data: data,
       block_id: block_id,
       members: socket.assigns.members,
       doc_members: socket.assigns.doc_members
     })}

In the hook I am listening to these events like so -

    this.handleEvent("table_data_init", (data) => {
      console.log(data.block_id)
      vue_table['b' + data.block_id].data = data
    })
    this.handleEvent("table_data_updated", (payload) => {
      let new_data = payload.data
      let data = vue_table['b' + new_data.block_id].data
      if (data.rows){
        data.rows = data.rows.map((r) => {
          if(r.id == new_data.row_id){
            r.modified_by = new_data.user_id
          }
          return r
        })

        let dp = data.data.filter((d) => d.table_column_id == new_data.col_id && d.table_row_id == new_data.row_id)
        if(dp.length == 1){
          data.data = data.data.map((d) => {
            if(d.table_column_id == new_data.col_id && d.table_row_id == new_data.row_id){
              d.value = new_data.value
            }
            return d
          })
        }else{
          let d = {
            table_column_id: new_data.col_id,
            table_row_id: new_data.row_id,
            value: new_data.value
          }
          let x = [...data.data, d]
          data.data = x
        }
      }
    })
    this.handleEvent("table_columns_updated", ({columns, block_id}) => {
      vue_table['b' + block_id].data.columns = columns;
    })
    this.handleEvent("table_column_deleted", ({columns, data, block_id}) => {
      vue_table['b' + block_id].data.columns = columns;
      vue_table['b' + block_id].data.data = data;
    })
    this.handleEvent("new_table_row_added", ({rows, block_id}) => {
      console.log("***********************************************")
      vue_table['b' + block_id].data.rows = rows;
      vue_table['b' + block_id].current_page = vue_table['b' + block_id].total_pages 
    })

Now the problem is when I make first request to liveview from the vuejs component using the hook -

this.pushEventTo(target, "event_name", {data: data})

I get a response from liveview which has 2 event calls, the table_data_init and the new one table_data_updated.

If i send another event from the vuejs component, I get reply from liveview which has 3 events. Like so -

This keeps repeating. So for 10th event I get a reply with 11 events and so on.

Can I prevent this? Can we make live_view send only the latest event and not all the events during the editing session?

Any help would be deeply appreciated.
Thanks to the community once again.

1 Like

It is a bug. I found the root cause looking at the code, I will push a fix soon.

4 Likes

Many thanks!!

Fixed in master!

7 Likes

Thats crazy fast. Thank you so much @josevalim. You are fantastic.

I got the same issue, thanks for fix, it helped to save a lot of time and I thought I am crazy. Couple of weeks ago I tried to implement toasts notifications and each new toast added additional one… I decided to postpone this job and now I see what was a reason.