skip to Main Content

Here’s the store:

import { ref } from "vue";

// Store for all data
export const countriesData = ref();
export const isLoading = ref(true);

async function getData() {
    try {
        isLoading.value = true;
        const response = await fetch("https://restcountries.com/v3.1/all");
        const data = await response.json();
        countriesData.value = data;
    } catch (error) {
        console.error("error", error);
    } finally {
        isLoading.value = false;
    }
}

getData();

// Store for filtered data
export const filteredData = ref(countriesData);

The countriesData should be updated once, with the async getData() and then never changed. filteredData does change, based on searching and filtering elsewhere in the app.

Here’s the search input code:

<script setup>
import { ref } from "vue";
import { countriesData, filteredData } from "../../store/store";

const searchValue = ref("");

function handleSubmit(e) {
    e.preventDefault();
console.log(countriesData.value.length);

    for (let i = 0; i < countriesData.value.length; i++) {
        console.log(countriesData.value.length);
        if (
            countriesData.value[i].name.common.toLowerCase() ===
            searchValue.value.toLowerCase().trim()
        ) {
            filteredData.value = [countriesData.value[i]];
            // setError(false);
            searchValue.value = "";
            return;
        } else {
            // setError(true);
        }
    }
}
</script>

For whatever reason, after running this for loop (which works, I get the correct country I search for), the original store, countriesData, changes to only give me countriesData.value[i].

filteredData should be countriesData.value[i], I have no idea why countriesData is also changing to countriesData.value[i].

The code

filteredData.value = [countriesData.value[i]];

in the loop seems to cause both filteredData and countriesData to change to countriesData.value[i], so if I comment that line out, the original countriesData store remains untouched.

How do I get only filteredData to change and leave countriesData untouched?

2

Answers


  1. We cannot be sure without a minimal reproductible example, but it looks like you are missing the .value when declaring the filteredData variable. What you are doing is basically saying filteredData should be equals to the "ref" countriesData. This might be why both variables are updated at the same time.

    In any case, if you want to make sure that both variable are not linked, you could deep copy the countriesData into the filteredData variable using the spread syntax.

    export const filteredData = ref([...countriesData.value]);
    

    This would ensure that the filteredData ref only contains a copy of the array contained in the countriesData.

    P.S. It looks like you are missing the await before your getData() call.

    Login or Signup to reply.
  2. When setting filteredData as a reference of countriesData, you are pointing towards the same value, so if you edit fileredData, you are unknowingly editing countriesData. In order to avoid this, if you want to store countriesData into filteredData, you need to generate a copy of countriesData.

    const filteredData = ref([...countriesData.value])
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search