PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, September 8, 2022

[FIXED] Why Vuejs does not want to update the model from the data received through AJAX

 September 08, 2022     ajax, javascript, vue.js, vuejs2     No comments   

Issue

Expectations:

The application should work as a socket, only data is received through periodic ajax requests to the server.

Problem:

When changing data on the "client (browser) No. 1", soon the data changes on the "client No. 2". BUT, if you now change the data on the "client number 2", then the changes on the "client number 1" does not occur.

Simply put, the data is not synchronized. The application does not notice changes in incoming data.

I can not understand the reason.

vuetest.php

<div id="app">
    <table border="1">
        <tr v-for="item in items"> 
            <td>
               <div @click="editCell" 
                    @focusout="saveCell" 
                    @keyup.enter="saveCell" 
                    >{{item.value}}</div> 
            </td>
        </tr>
    </table>
</div>

vuetest.js

var app = new Vue({
    el: '#app',
    created() {
        this.intervalTrigger();
        this.fetchData();       
    },
    data: {  
        "items":[]
    },
    methods: {
        fetchData() {            
            if (this.intervalId === 0){
                this.intervalTrigger();
            }

            var bodyFormData = new FormData();
            bodyFormData.set('module', 'vueTest');  
            bodyFormData.set('command', 'getData');  

            axios({
                method: 'post',
                headers: { 'content-type': 'application/x-www-form-urlencoded' },
                url: '/vueajax.php',
                data: bodyFormData
            })
            .then(response => { 
                this.items = response.data.items;
            }); 
            return; 
        },
        sendAjax(data){
            var bodyFormData = new FormData();
            var answer;
            $.each(data, function(i, obj) {
                bodyFormData.set(''+ i +'', obj);
            });           
            answer = axios({
                method: 'post',
                headers: { 'content-type': 'application/x-www-form-urlencoded' },
                url: '/vueajax.php',
                data: bodyFormData
            }); 

            return answer;
        },
        intervalTrigger: function () {
            this.intervalId = window.setInterval( function() {
             app.fetchData()
            }, 5000 );
            return this.intervalId;
        },
        editCell: function(e){
            if($(e.target).is('.bg-edit')) return;
            $(e.target).attr('contenteditable', 'true');
            $(e.target).addClass('bg-edit');
            $(e.target).focus();
        },
        saveCell: function(e){
            var value = $(e.target).text();
            var answer;
            $(e.target).html(value);
            var data = {
                'module': 'vueTest', 
                'command': 'setValue',
                'value': value
            };
            answer = this.sendAjax(data);
            answer.then(response => { 
                $(e.target).text(response.data.result);
            });
            $(e.target).removeAttr('contenteditable', 'true');
            $(e.target).removeClass('bg-edit');
        }
    }
});

vueajax.php

<?php

if ($_POST['module'] === 'vueTest'){

    if ($_POST['command'] == 'setValue'){
        $new_value = (int) $_POST['value'];
        file_put_contents("vuetest.txt", $new_value);
        echo json_encode(["result" => $new_value]); die;
    } else {
        $value = (int) trim(file_get_contents("vuetest.txt"));
    }

    echo json_encode(
            [
                "items" => [
                    0 => ["value" => $value]
                ]
            ]
        );
    die;

Solution

Generally speaking, these issues are down to Vue's issues with reactivity and arrays: https://v2.vuejs.org/v2/guide/reactivity.html

With this in mind, you could try:

this.$set(this, 'items', response.data.items) instead of this.items = response.data.items

This forces Vue to rebind that instance variable with the new items instead.

It's also worth noting, you need a key on your loop:

<tr v-for="item in items" :key="item.id"> - You'll likely have a console error stating the same.



Answered By - webnoob
Answer Checked By - Pedro (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing