The v-for loop seems to only update the last element instead of all of them, which is incorrect

How can I ensure that all 3 page links in the nav are displayed in 3 languages of user choice? Initially, the language change works fine on page load. However, after clicking on a language change link once, only the last link's language changes instead of all of them. What is causing this issue and how can it be resolved?

app.vue:

<template>
    <nav class="navbar">
        <NuxtLink class="pagelink" :key="page.slug" v-for="page in strings.pages" :href="'/' + page.slug">{{ page.name[lang] }}</NuxtLink>
        <Languages />
    </nav>
</template>
<script>
import Languages from "./components/languages.vue"
import languages from "../services/languages"
export default {
    name: "Navbar",
    data() {
        return {
            open: false,
            strings: {
                pages: [
                    {
                        slug: 'home',
                        name: { az: "Əsas", ru: "Главная", en: "Home" }
                    },
                    {
                        slug: 'about',
                        name: { az: "Haqqımızda", ru: "О нас", en: "About" }
                    },
                    {
                        slug: 'contact',
                        name: { az: "Əlaqə", ru: "Связаться", en: "Contact Us" }
                    }
                ]
            }
        }
    },
    computed: {
        lang() {
            return languages(this)
        }
    }
}
</script>

<style>
* {
    margin: 10px;
}
</style>

languages.vue:

<template>
    <div class="languages">
        <NuxtLink :to="route.path + '?hl=az'">AZ</NuxtLink>
        <NuxtLink :to="route.path + '?hl=ru'">RU</NuxtLink>
        <NuxtLink :to="route.path + '?hl=en'">EN</NuxtLink>
    </div>
</template>

<script>
export default {
    name: "Languages",
    setup() {
        const route = useRoute()
        return {
            route
        }
    }
}
</script>

<style scoped>
div,
div a {
    height: 40px;
    display: inline-block;
}

img {
    height: 60%;
    display: inline-flex;
    margin: 8px;
}
</style>

languages.js:

function languages(page) {
    let langCookie = useCookie("language")
    let language = langCookie.value
    if (page.$route.query.hl) {
        language = page.$route.query.hl
        langCookie.value = language
    }
    return language || 'az';
}

export default languages

Answer №1

The main issue I've noticed in your code is the manipulation of the cookie within the languages function, which is called by your lang computed property.

A computed property should not have side effects, as stated in the Vue documentation.

You should separate the logic and only return the current language or a default value in the computed property.

setup() {
    let langCookie = useCookie('language');

    return {
      langCookie
    }
},

computed: {
    lang() {
        return this.langCookie || 'az';
    }
}

The code to update the language in the cookie should be extracted and only called when needed. For example, you could trigger it when the user clicks on a language link in the selector or use an immediate watcher on the language value from the URL.

<template>
  <div class="languages">
    <!-- Only update the query parameters for the language selection, vue-router will handle the URL computation -->
    <NuxtLink :to="{ query: { hl: 'az' } }">AZ</NuxtLink>
    <NuxtLink :to="{ query: { hl: 'ru' } }">RU</NuxtLink>
    <NuxtLink :to="{ query: { hl: 'en' } }">EN</NuxtLink>
  </div>
</template>

<script>
import { watch } from 'vue';
import { useRoute } from 'vue-router';
import { useCookie } from '?';

export default {
  name: 'Languages',

  setup() {
    const route = useRoute();
    const langCookie = useCookie('language');

    watch(
      () => route.query.hl,
      (newLang) => {
        langCookie.value = newLang;
      },
      {
        immediate: true
      }
    );
  }
}
</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to display long text in a browser alert without it being cut off?

Seeking to display a large amount of data in an alert box, but only a portion is currently visible. The following text is all that can be seen: ["19467,1496257152583","19227,1496256651094","19469,1496257033968","17285, ...

Experience the power of Kendo UI Date Picker combined with AngularJS. When the datepicker is initialized, it starts

Check out my code snippet below: When the datepicker loads initially, it appears empty. However, if you remove ng-model from the directive template, the datepicker displays its initial value correctly. Yet, changing the selected date does not mark the fo ...

Pinterest-style Angular-UI-Router modal

I am currently working on an app that features a gallery showcasing similar functionalities to . In Pinterest, clicking on a pin displays the pin page above the existing gallery without any information about the background gallery shown in the URL. Users c ...

Managing code requiring document.title in Next.js with Static Site Generation (SSG)

Currently, I have 2 dynamic SSG pages located under /blog/[slug]. Within these pages, I am rendering a component using next/link. When I click on these links to navigate to another slug, I encounter an issue. The problem arises when I want to execute some ...

The ".splice()" method continuously removes the final element from an array

I have implemented a function on my form that allows me to add multiple file inputs for various images by clicking a button. Although this functionality is working correctly, I am facing an issue while trying to delete an input field using .splice. Instead ...

Unable to adjust the x-axis time display in Chart.js

Within my ChartData Component, I am fetching data from an API and displaying it through a chart. The crucial aspect here is the determine Format Logic, which determines the time format of the data. My main challenge lies in changing the time display when s ...

Retrieve documents from MongoDB that were created within the last week and return a count of 0 for any days in which no documents were created

I need to extract documents from the last 7 days stored in my Mongo Database. I have successfully retrieved data in the desired format, where specific dates and the number of tickets created on those dates are returned: { "datesUsed": { ...

Managing the position of the caret within a content-editable div

I need help with editing a contenteditable div in HTML <div contenteditable="true" id="TextOnlyPage"></div> Here is my jQuery code: var rxp = new RegExp("(([0-9]+\.?[0-9]+)|([0-9]+))", "gm"); $('#TextOnlyPage').keyup(function( ...

Guide to using the Firefox WebExtensions API to make AJAX requests to the website of the current tab

I am trying to develop a web extension that will initiate an AJAX call to the website currently being viewed by the user. The specific endpoint I need to access on this website is located at /foo/bar?query=. Am I facing any obstacles in using either the f ...

Vue - Additional loading may be required to manage the output of these loaders

Currently working with Vue and babel. I have a function that's been exported // Inside file a.js export async function get() { ... } I am trying to link this exported function to a static method of MyClass // Inside file b.js import myInterface fr ...

Designing multiple button actions in v-card-actions in Vuetify: A step-by-step guide

Trying to streamline the v-card-actions on my Vuetify v-cards. My aim is to center the test button within the v-card and position it above the like and share "footer" buttons. I want the like and share footer buttons to be at the bottom of the v-card with ...

injecting a variable from the configuration service into a TypeScript decorator

I am interested in setting up a scheduled task for my NestJs application to run at regular intervals. I found information on how to use intervals in the NestJs documentation. Since my application uses configuration files, I want to keep the interval value ...

Can you display a popup on a leaflet map from beyond its boundaries?

Utilizing leaflet maps, I have implemented a functionality where clicking on the map opens a popup at a specified location and centers on that position. The code for this is as follows: var popup = L.popup(); function onMapClick(e) { popup . ...

Text in SVG file misaligned at the edge

After creating an SVG with a base64 background image and two text areas for top and bottom texts, I encountered an issue on Internet Explorer and Edge. The problem is that the bottom text is aligned to the left instead of the center, and its position is in ...

Efficient methods for transferring information between a main and pop-up page within angularjs

On my webpage, I have a button that opens a popup page. I need to figure out a way to transfer json data from the main page to the popup page. These two pages are running separate angular applications. Once the data is transferred, it will be updated base ...

Having trouble assigning the current page in NextJS navigation

I have a unique setup for my navigation system in my NextJS project: const menu = [ { name: 'Home', href: '/home', icon: HomeIcon, current: true }, { name: 'About', href: '/about', icon: InfoIcon, current: fa ...

Strategies for effectively validating email addresses in Laravel 10 and Vue 3

Currently, my application is utilizing Laravel 10 with Vue 3. It is hosted on a server as a Web App, with a HTTP URL. However, the hosting provider's support team has informed me that all requests are automatically redirected to HTTPS due to the SSL ...

Is there a way to integrate a calendar feature within an Angular 2 application?

I am brand new to Angular 2 and have a question: I need to integrate a calendar into a page where users can add events. Something similar to the following example: I'm unsure if the angular material calendar project is designed for Angular 2 or for ...

Consolidate all data connected to the specified key from a JSON dataset

Looking at the json string presented below [{"_id":"9/17/2015","amt1":0,"amt2":13276.5},{"_id":"9/18/2015","amt1":8075,"amt2":6445.5}] The expected outcome is: [{"_id": ["9/17/2015", "9/18/2015"], "amt1": [0, 8075], "amt2": [13276.5, 6445.5]}] Is there ...

Using Javascript Reduce to Manipulate Objects

Here is the data I am working with: let info = [ {id: 1, name: "John Doe", type: "A", amount: 100}, {id: 2, name: "Jane Smith", type: "B", amount: 150}, {id: 3, name: "Alice Johnson" ...