Obtaining RestAPI data through axios in Vuex actions: a step-by-step guide

I attempted to utilize Axios in the actions of my Vuex system to retrieve data from a RestAPI and then display it in components. To test this out, I created a small app using a sample API, but encountered an error.

The API I used can be found here. It contains 5 keys: "postId", "id", "name", "email", and "body". For my app, I only needed to display the "id" information in my component. However, I kept getting an error message that said "TypeError: Cannot read property 'id' of undefined."

Here is a snippet of my Vuex code:

    import { MutationTree, ActionTree, GetterTree } from "vuex";
import { RootState } from "../types";
import { Customer } from "../types/customer";
import axios from "axios";

interface State {
  customer: Customer;
}
export const state = () => ({
  customer: []
});
export const getters: GetterTree<State, RootState> = {
  customer: (state: State) => state.customer
};
export const mutations: MutationTree<State> = {
  setCustomer(state: State, customer: Customer) {
    state.customer = customer;
  }
};
export const actions: ActionTree<State, RootState> = {
  getCustomerInfo: async ({ commit }) => {
    const data = await axios.get(
      "https://jsonplaceholder.typicode.com/posts/1/comments"
    );
    commit("setCustomer", data.data.customer);
  }
};
export default {state,getters,mutations,actions}

In order to define the types for RootState and Customer, I created separate files in the types directory:

export interface RootState {}
   export interface Customer {
    postId?: number;
    id?: number;
    name?: string;
    email?: string;
    body?: string;
  }

Lastly, here is a snippet of my Vue component:

<template>
  <div>
    <Counter />
    <p>vuex test</p>
    <p>{{ customer.id }}</p>
  </div>
</template>
<script lang="ts">
import { Component, namespace, Vue } from 'nuxt-property-decorator'
import { Customer } from '~/types/customer'
const SCustomer = namespace('customer')

@Component({})
export default class extends Vue {
  @SCustomer.Action getCustomerInfo!: Function
  @SCustomer.State customer!: Customer

  async created() {
    await this.getCustomerInfo()
  }
}
</script>

If anyone could offer some advice on how to properly set the data in the mutations through actions, I would greatly appreciate it!

Answer №1

Ensure that the request is successful and data is present in the state before proceeding with mutations. It is necessary to have a getter to access the state data. Make sure you can access the state Actions or use mapActions if needed. This guidance should assist you.

import { MutationTree, ActionTree, GetterTree } from "vuex";
import { RootState } from "../types";
import { Customer } from "../types/customer";
import axios from "axios";

interface State {
  customer: Customer;
}
export const state = () => ({
  customer: []
});
export const getters: GetterTree<State, RootState> = {
  customer: (state: State) => state.customer
};
export const mutations: MutationTree<State> = {
  setCustomer(state: State, customer: Customer) {
    state.customer = customer;
  }
};
export const actions: ActionTree<State, RootState> = {
  getCustomerInfo: async ({ commit }) => {
    const data = await axios.get(
      "https://jsonplaceholder.typicode.com/posts/1/comments"
    ).then((response) => {
        if(response.status === 'success'){
            commit("setCustomer", data.data.customer);
        }
   })
  };
};
export default {state, getters, mutations, actions}

Within the Vue instance

<template>
  <div>
    <Counter />
    <p>vuex test</p>
    <p>{{ customer.id }}</p>
  </div>
</template>
<script lang="ts">
import { Component, namespace, Vue } from 'nuxt-property-decorator'
import { Customer } from '~/types/customer'
const SCustomer = namespace('customer')

@Component({})
export default class extends Vue {
  @SCustomer.Action getCustomerInfo!: Function
  @SCustomer.State customer!: Customer

    computed: {
       ...mapGetters(['customer'])
    },

    created() {
        this.getCustomerInfo()
    }
}
</script>

Answer №2

Within the test.vue document, I made a modification from {{customer.id}} to {{customer}} in the template.

In store/customer.ts, I adjusted the actions function accordingly.

The line commit('setCustomer',data.data.response) was changed to commit('setCustomer',data.data)

In the initial code, I received data from a test API, but my request data code was incorrect. A big thank you to Mr.Kimsea Sok for the helpful advice!

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

How can we avoid excessive re-rendering of a child component in React when making changes to the parent's state?

In my React application, I am facing a situation where a parent component controls a state variable and sends it to a child component. The child component utilizes this state in its useEffect hook and at times modifies the parent's state. As a result, ...

"Discover the best way to retrieve data within a Vuex store during the mounted or created lifecycle functions

After storing data in Vuex, I encountered an issue when trying to access my Vuex store after changing routes (components). When inside the mounted function, it shows me an error and fails to return the data. How can I resolve this? I am aware that using a ...

Convert the union into a mapped structure

Starting with the given Union type: type Union = { type: 'A', a: string } | { type: 'B', b: number } The end goal is to transform it into this MappedUnion type: type MappedUnion = { A: { type: 'A', a: string } B: { ...

One way to consolidate multiple components in a single location without altering user-input data

I currently have 3 separate components, namely PersonalInfoComponent, EducationalInfoComponent, and ExperienceComponent. These components are all being displayed within the ResumeComponent. The issue I am facing is that when a user enters information in t ...

Issue with setting cookies on the client side when using NodeJS, VueJS, and express-session

I have been working on an app that already has its own infrastructure. My current task is to integrate a session-cookie mechanism, but I've been struggling to make the cookies set on the client side after spending a significant amount of time investig ...

Is there a way to utilize the child component's method?

I am looking to access a child component's method from the parent in Vue.js. To achieve this, I plan on using $refs. Code Example: <template> <div>Parent!</div> </template> Script: <script> Vue.component('c ...

Transferring a document using axios to the Laravel framework

I am currently utilizing the Quasar file picker to capture files from users and send them to a Laravel controller using Axios. However, when I send the data to the Laravel controller, I am receiving an empty object. Can someone assist me in resolving this ...

How can a child component trigger an event in its parent component?

Currently, I have tabs implemented with a form and a button in tab1. In the parent component, there is an event that deactivates the current tab and activates the next one. Can anyone advise on how to call this event from the child component? gotosecond ...

Improving presentation of a 5MB query outcome with Python and VueJS

I am currently working on a web application that utilizes Python (bottle) on the server and VueJS on the client side. One of my frontend components is responsible for displaying paginated results from a query that returns over 10,000 records. These records ...

Can two different versions of a library be utilized simultaneously in NPM?

Currently, our Vue.js app is built with Vuetify v1.5 and we are considering transitioning to Vuetify 2.0. However, the process would involve numerous breaking changes which we currently do not have the resources to address for all components. Is there a wa ...

Using React and TypeScript to Consume Context with Higher Order Components (HOC)

Trying to incorporate the example Consuming Context with a HOC from React's documentation (React 16.3) into TypeScript (2.8) has been quite challenging for me. Here is the snippet of code provided in the React manual: const ThemeContext = React.creat ...

What is the process for bringing a graphql file into typescript?

I'm having trouble importing a graphql file and encountering an error import typeDefs from "./schema/schema.graphql"; 10 import typeDefs from "./schema/schema.graphql"; ~~~~~~~~~~~~~~~~~~~~~~~~~ at cre ...

The Angular 6 View does not reflect changes made to a variable inside a subscribe block

Why isn't the view reflecting changes when a variable is updated within a subscribe function? Here's my code snippet: example.component.ts testVariable: string; ngOnInit() { this.testVariable = 'foo'; this.someService.someO ...

Template for typed variable - `ng-template`

How can the parent component correctly identify the type of let-content that is coming from ngTemplateOutletContext? The current usage of {{content.type}} works as expected, but my IDE is showing: unresolved variable type Is there a way to specify the ...

Experience the dynamic synergy of React and typescript combined, harnessing

I am currently utilizing ReactJS with TypeScript. I have been attempting to incorporate a CDN script inside one of my components. Both index.html and .tsx component // .tsx file const handleScript = () => { // There seems to be an issue as the pr ...

Call a function within a stateless component in a React application

I have a question regarding my React component. I am attempting to call the function ButtonAppBar within my stateless component, but the TypeScript compiler is throwing an error stating '{' expected. I'm unsure whether I need to pass it to m ...

Is there a way to determine if a string is empty, even if it contains hard returns?

I am currently working on a function that checks if a string is empty or not, but it seems to be missing the detection of new lines. export const isStrEmpty = function(text: string): boolean { return !text || text.match(/^ *$/) !== null; }; I attempted ...

The child route's vue-router named view is failing to function accurately

The nested route with a named router view is not loading correctly. When clicking the links in the navigation drawer, the corresponding content should be displayed in the v-content component. I have implemented this using named router views. Below are the ...

Injecting HTML into Vue component

Currently, I am passing some parameters into a Vue component <Slider :images= "['/img/work/slide2.png', '/img/work/slide2.png', '/img/work/slide3.png']" :html="['<div>hello</div>', ' ...

Tips for integrating Vuex store with router for seamless accessibility

Hey there! I'm currently working on a Vue project that involves using both vue-router and vuex. In my application, after a successful login, I store the JWT token in vuex. However, I am facing challenges with the following: 1) How to dynamically show ...