0

I have a VUE 3 application where we are experiencing some sync issues when clicking on our toggles.

When the toggle is clicked, the app is supposed to call our API with the updated list.

THE PROBLEM: When the toggle is clicked the data within the computed property is correct. We are then emitting that data to the parent component (data is still correct when received at the parent component).

Parent component calls the API which updates the data. But in the request body, the data is not correct, that is still the old list. If I click on one of the toggles again the data being sent is then correct from the previous update (it is one click behind).

Here are the steps the app is going through:

  1. A vue component emits computed property to the parent component
    // CHILD COMPONENT EMITTING DATA TO PARENT

    ____filters.vue___

    <template> 
           <ion-toggle
                @click="changedFilter"
                v-model="filter.selected"
                :checked="filter.selected"
                slot="end">
           </ion-toggle>
    </template>

    
    setup(props, context) {

        const changedFilter = () => {
            console.log(props.searchFiltersArr)   ------> **THIS DATA IS CORRECT**
            context.emit("changedFilter", props.searchFiltersArr);  
        };

        return {
            changedFilter,
            filters: props.searchFiltersArr,
        };
    }
  1. Parent component receives emitted data from the child and calls the API using Axios.
       ___ SearchFilters.vue _____

       <template>
            <filters
                @changed-filter="updateFilter"
                :searchFiltersArr="searchParameters">
            </filters>
       </template>

export default defineComponent({
    name: "SearchFilters",
    components: { Filters },
    setup() {
        const store = useStore();

        const searchParameters = computed(() => {
            return {
                searchParameters: store.state.user.settings.searchParameters,
            };
        });

        async function updateFilter(search: Array<SearchFilter>) {
            const headers = {
                "Content-type": "application/json",
                Authorization:
                    "Bearer " + "21345",
            };
            const requestBody = {
                user: {
                    name: "",,
                    email: "email@email.com",
                },
                searchParameters: search,
            };
            console.log(requestBody);       -----------> **REQUEST BODY HAS THE CORRECT VALUES FROM CHILD COMPONENT**


            await apiClient.put("/settings", requestBody, {
                headers,
            }); -----> ** REQUEST BODY IN THE ACTUAL REQUEST IS NOT THE UPDATED CONTENT **
        }

        return {
            updateFilter,
            searchParameters: searchParameters.value.searchParameters,
        };
    },
});

The updated data is correct all the way until we call the service. Then the body is incorrect. How can this be?

If i wrap the axios request inside of a set timeout like so, it works.

setTimeout(function (){ 
axios service }, 2000) 

Let me know if you need any further information. This is just a simplified example, as this shows the problem. In the real application we are calling a vuex action which then call the api and thereafter commits the updated state. The issue is exatcly the same though.

The problem is somewhat similar to this post - ReactJS - synchronization issue with axios.post

Anfield_08
  • 73
  • 1
  • 10
  • Possible duplicate of https://stackoverflow.com/questions/17546953/cant-access-object-property-even-though-it-shows-up-in-a-console-log – Estus Flask Aug 24 '21 at 13:14
  • **THIS DATA IS CORRECT** - It's not, you have a fundamental problem with debugging. Don't use the console as the primary debugging tool if you have the access to real debugger. – Estus Flask Aug 24 '21 at 13:15
  • A shit, that's rigth. using console.log(JSON.parse(JSON.stringify(requestBody))); shows the correct state – Anfield_08 Aug 24 '21 at 13:22

1 Answers1

0

I found a solution to the problem. Since vue can’t guarantee the order of events (computation should run before click event), I removed the click event and added a watcher instead

Anfield_08
  • 73
  • 1
  • 10