Issues with Vuex store causing incorrect value retrieval

In troubleshooting this issue, I am encountering a problem. My request to the back end is to retrieve data for display on the front end. The data fetched from the backend consists of recipes stored in an array. Utilizing v-for, I iterate through the array and create router-link elements to navigate to each individual recipe. Upon clicking a recipe link, I aim to display its details on the right side of the screen. However, when retrieving the recipe object from the database upon link click, I notice that the ID retrieved is incorrect.

VUEX MODULE

const state = {
 recipes: [],
 singleRecipe: {}
};

const mutations = {
 'RECIPES_LIST'(state, recipes) {
 state.recipes = recipes;
},
'GET_RECIPE'(state, response) {
 const recipe = response; // THIS IS THE RIGHT RESPONSE 
 state.singleRecipe =  recipe;
 }
}

const actions = {
  initRecipes: ({commit}) => {
  axios.get('http://localhost:3000/recipes')
  .then((response) => {
    commit('RECIPES_LIST', response)
  })
  .catch(err => {
    console.log(err);
  });
  },
  getRecipe: ({commit}, id) => {
   axios.get('http://localhost:3000/recipes/' + id)
  .then(response => {
    const recipe = JSON.stringify(response);
    commit('GET_RECIPE', recipe); // RIGHT RECIPE
  })
  .catch(err => console.log(err));
  },

 const getters = {
 recipes: state => {
 return state.recipes;
 },
  singleRecipe: state => {
   return state.singleRecipe;
  }
};

RECIPE LIST COMPONENT

   <template>
  <div>
    <div class="col-md-6">
      <router-link :to="'/recipes/' + recipe.id"  v-for="recipe in 
 recipes.data">
        <div id="list"  class="panel">
          <div class="panel-body">
            <div class="pull-left">
              <h4>{{recipe.title}}</h4>
            </div>
            <div class="pull-right">
              <img class="img-responsive" :src="recipe.picture" style="width: 80px; height: 80px;">
             </div>
          </div>
        </div>
      </router-link>
    </div>
    <div class="col-md-6">
      <router-view></router-view>
    </div>
  </div>
</template>
<script>
  export default {
    computed: {
      recipes() {
        return this.$store.getters.recipes;
      }
    }
  }
</script>

RECIPE DETAILS COMPONENT

<template>
  <div class="panel" @click="getSingleRecipe">
    <div class="panel-heading">
      <!--<h1>{{recipe.data.title}}</h1>-->
    </div>
    <div class="panel-body">
      <!--<p>{{recipe.data.description}}</p>-->
      <p>Ingredients: </p>
      <ul>
        <li v-for="i in recipe.ingredients">{{i.ingredient}}</li>
      </ul>
      <router-link :to="{name: 'Update', params: {id: id}}"><button class="btn btn-primary">Update Recipe</button></router-link>
      <button class="btn btn-danger" @click="deleteRecipe">Delete Recipe</button>
    </div>
  </div>
</template>
<script>
  import { mapActions } from 'vuex';
  export default {
   data() {
     return {
    id: this.$route.params.id,
    recipe: {}
      }
    },
    watch: {
  '$route' (to, from) {
    this.id = to.params.id;
    this.getSingleRecipe();
        console.log('CHANGEEEEEE' + this.recipe); // GETS RECIPE WITH ID (example 4)
        console.log("ACTIVEEEEEEE ID" + this.id); // GETS RIGHT ID (example id: 2)
      }
    },
   ...mapActions({
      deleteTheRecipe: 'deleteRecipe',
      initRecipes: 'initRecipes',
      getRecipe: 'getRecipe'
      }),
      deleteRecipe() {
    this.deleteTheRecipe(this.id);
    this.initRecipes();
    this.$router.push('/recipes');
  },
      getSingleRecipe() {
         this.getRecipe(this.id);
         this.recipe = this.$store.getters.singleRecipe;
      }
    },
    created() {
      this.getSingleRecipe();
      console.log("CREATED ID" + this.id);
      console.log('CREATEDDDDD ' + JSON.stringify(this.recipe));
    }
  }
</script>

Answer №1

Consider relocating your id property from data to a computed property. It appears that the data.id property may not be reacting to changes in route.params after the component has been rendered.

Another approach to loading a recipe when the route changes is by utilizing the beforeEnter function on your router.

import store from '../store'

beforeEnter: (to, from, next) => {
    store.dispatch(getRecipe, to.params.id)
      .then(() => {
        next()
      })
  }

This method eliminates the need to monitor the router in your component. Utilize mapGetters to access the recipe from the store.

computed: {
  ...mapGetters({
    recipe: 'singleRecipe'
  })
}

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 construct a template string to display the contents of an object?

Here is an array of objects: var students = [ { name : "Mike", track: "track-a", points : 40, }, { name : "james", track: "track-a", points : 61, }, ] students.forEach(myFunction); function myFunction (item, index) ...

Exploring a collection of objects using a filter and specific keyword

I am looking to implement a search functionality in JavaScript using an array, filter, and keyword. The goal is to search through the array based on the filter and keyword provided, and return a new array of objects similar to the original one. var data ...

A guide on implementing lazy loading for components and templates

I have successfully implemented lazy loading for components and templates individually, but I am struggling to combine the two. Here's an example of how I lazy load a component: // In my main.js file const router = new VueRouter({ routes: [ ...

Is it possible to Vue CLI build for an external host?

Currently, I am working on a Vue CLI application that implements code splitting for JS and CSS. When running npm run build, the application generates nearly 1,000 JS/CSS files. The issue arises when hosting this application on Google Cloud Run, as it resul ...

A guide to updating property values in an array of objects in JavaScript while ensuring they remain in consecutive order

I am dealing with an array of objects called list. The parameters rid and rorder are provided for processing. -> 1. Whenever the value of rid matches the id in the list, the itemorder is updated with the value of rorder. -> 2. In the updated list p ...

Utilize Javascript to refine JSON data strings

Currently, I am tackling a small project and facing a minor JS issue. The JSON string that I have looks like this: var jsObj = { "templates": { "form0": { "ID": "MyAlertNew", "isVisible": "true", ...

Encountering Challenges when Implementing Next.js with Jest

When attempting to run a test in next.js using jest, an error keeps appearing: The issue may be due to the wrong test environment being used. Refer to https://jestjs.io/docs/configuration#testenvironment-string for more information. Consider utilizing the ...

The Socket.io server is experiencing issues with the "connection" event not firing, and the client event is also not being triggered

I've been struggling to set up an express backend with socket io. No matter what I try, the connection events just won't fire. Both the server and client are using version 3.1.2, so that's not the issue. When I start the client app, I see so ...

Utilizing Input Data from One Component in Another - Angular4

As a newcomer to Angular, I'm facing an issue where I need to access a variable from ComponentA in ComponentB. Here's the code snippet that demonstrates what I'm trying to achieve (I want to utilize the "favoriteSeason" input result in the " ...

Need some assistance with Javascript Ajax? Specifically, dealing with multiple values?

My goal is to asynchronously post an array of messages using this code. Despite my efforts, I've encountered a challenge where it doesn't only post the four items in the array but also adds gibberish text. Additionally, there seems to be an issue ...

Kendo's data-bind onclick feature functions properly on web browsers but fails to work on mobile devices

As a newcomer to Kendo and JavaScript, I may be missing something obvious... In one of my list entries, I have a simple call like this: <li style="margin: 0.5em 0 0.5em 0"> <a href="#transaction-details" data-bind="click: onB ...

What is the best way to display an image in HTML?

I have successfully created an autocomplete search box that retrieves product names, but I am struggling to display the product photos. Here is the code snippet I am using: <asp:TextBox ID="txtContactsSearch" runat="server" Width="261"></asp:Text ...

Custom CSS for the Google Maps Circle Object

Currently, I am utilizing the Google Maps Javascript API v3 Circle object to display circles on the map. I am interested in customizing the CSS of this circle by incorporating some CSS animations. Although I am aware that custom overlays can be used for t ...

Is there a reason why angularJS doesn't provide the exact error location directly, opting instead to just offer a link to their website that provides a generic explanation?

Why does AngularJS not provide the specific error location directly, such as which file the error is in, instead of just giving a link to their website with a generic explanation? This makes debugging very challenging! Whenever there is an error, it becom ...

Issue: [vuex] Modifying vuex store state through Firebase Auth Object outside of mutation handlers

I'm having trouble solving this issue after spending a few hours on it. Can anyone help me identify the problem? The error message I keep encountering reads: Error: [vuex] Do not mutate vuex store state outside mutation handlers Below is the section ...

Utilizing a material-ui button within a React application as the trigger for a Popup using MuiThemeProvider

I want to trigger a Popup in React using a button with a custom theme: <PopUp modal trigger={ <MuiThemeProvider theme={buttonTheme}> <Button variant="contained" color="secondary">Excluir& ...

What is the best way to send a function to the child component?

I need help with passing a function to a child component in React. Specifically, I have a component with a modal for confirming the deletion of an item. How can I pass a delete function to the modal so that when the "Agree" button is clicked, it triggers t ...

Tips for managing the velocity of JavaScript navigation scrolling

Hey everyone, I recently discovered this incredibly helpful JavaScript sticky side navigation script and it works like a charm! However, since I don't know much about JS, I was wondering if there's a way to slow down the scrolling speed? functio ...

Create a placeholder for the module function

Update: Providing more specific details. Our team has developed a Github API wrapper extension and we are looking to test different use cases for it. However, we prefer not to use the API wrapper extension directly during testing and instead want to stub ...

Is it possible to implement a custom radio tab index without using JavaScript

Is it possible to apply the tabindex attribute on custom radio buttons, hide the actual input element, and use keyboard shortcuts like Tab, Arrow Up, and Arrow Down to change the value? Check out this example on StackBlitz ...