How to fetch db query with relationshiep using axios and vuex


#1

i’m trying to load an eloquent relationship to update vuex state using axios, i will explain what i’m doing to the best of my ability.

i have a theme to color relationship on the theme controller like this

this is the actual array

{
id: 1,
wide: true,
bg_style: "image",
bg_color: "#eff8ff",
bg_image: "/storage/theme/background.jpg",
gradient: false,
bg_gradient_color_a: "rgba(52,144,220,1.0)",
bg_gradient_color_b: "rgba(28,61,90,1.0)",
angle: "0deg",
shadowstatus: false,
shadow: "shadow-lg",
overlay: true,
overlay_color_a: "rgba(52, 144, 220, 0.0)",
overlay_color_b: "rgba(52, 144, 220, 1.0)",
overlayangle: "180deg",
title: "font-sans",
subtitle: "font-sans",
description: "font-sans",
text: "font-sans",
menu: "font-sans",
analytics: "",
created_at: "2019-01-31 10:43:55",
updated_at: "2019-01-31 10:47:08",
colors: [
{
id: 1,
theme_id: 1,
color: "rgba(0, 0, 0, 0.0)",
created_at: null,
updated_at: null,
},
{
id: 2,
theme_id: 1,
color: "rgba(52, 144, 220, 1.0)",
created_at: null,
updated_at: null,
},
{
id: 3,
theme_id: 1,
color: "rgba(244,109,155,1.0)",
created_at: null,
updated_at: null,
},
{
id: 4,
theme_id: 1,
color: "rgba(101,116,205,1.0)",
created_at: null,
updated_at: null,
},
{
id: 5,
theme_id: 1,
color: "rgba(149,97,226,1.0)",
created_at: null,
updated_at: null,
},
],
}

in my theme component i dispatching a function to load and update the theme : [] state like this

  mounted () {

    this.$store.dispatch('getThemeSettings');

  },

this is part of my store.js file

// this is parts of my vuex store file
import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';

Vue.use(Vuex, axios);

export const store = new Vuex.Store({

    state:{

        theme : [],

       // ..... etc
    
    },

    mutations: {

        SET_THEME (state,themeData){

            state.theme = themeData;

        },
    },

    actions: {

        getThemeSettings: function({commit}){

            axios.get('/admin/designer/api/theme')
                
                .then(response => {

                    this.theme = response.data;

                    let themeData = response.data;

                    commit('SET_THEME', themeData)

                })

            .catch( error => {

                  Event.$emit('requestAlertDanger');

            })
        
        },
    },
 })

Unfortunately i’m not being able to get the theme query with colors relationship.

Any ideas.


#2

You’ll have to expand on this. Do you get a response from the endpoint at all? Are you getting errors? If it’s an endpoint response related issue then this wouldn’t be anything to do with Vue or Axios.


#3

@JamesThomson i made some changes to the code, this is the new post


#4

Ok, thanks. But it still doesn’t answer my original question.


#5

Yes i’m getting the correct collection from the inPoint using axios, the issues im facing is how to add the state properly to the navbtns array (full collection with submenu)

// this is the array  with navbtns containing the submenu buttons

[
{
id: 3,
language_id: 2,
name: "services",
sort: 2,
icon: "fas fa-desktop",
link_type: "page",
link_page: "services",
link_web: "https://linxtter.com",
link_email: "name@mywebsite.com",
link_phone: "+99999999999",
link_file: "",
target: "",
created_at: "2019-02-07 19:56:30",
updated_at: "2019-02-07 19:56:30",
submenu: [
{
id: 3,
navigation_id: 3,
name: "home",
description: "Description goes here",
sort: 1,
icon: "far fa-grin-hearts",
link_type: "page",
link_page: "/من-نحن",
link_web: "https://linxtter.com",
link_email: "name@mywebsite.com",
link_phone: "+99999999999",
link_file: "",
target: "",
created_at: "2019-02-07 19:56:30",
updated_at: "2019-02-07 19:56:30",
}
],
},
{
id: 2,
language_id: 2,
name: "services",
sort: 5,
icon: "far fa-grin-hearts",
link_type: "page",
link_page: "/خدماتنا",
link_web: "https://linxtter.com",
link_email: "name@mywebsite.com",
link_phone: "+99999999999",
link_file: "",
target: "",
created_at: "2019-02-07 19:56:30",
updated_at: "2019-02-07 19:56:30",
submenu: [ ],
},
{
id: 6,
language_id: 2,
name: "home",
sort: 5,
icon: "fas fa-home",
link_type: "page",
link_page: "services",
link_web: "https://linxtter.com",
link_email: "name@mywebsite.com",
link_phone: "+99999999999",
link_file: "",
target: "",
created_at: "2019-02-07 19:56:30",
updated_at: "2019-02-07 19:56:30",
submenu: [ ],
},
]



#6

Ok, good. I don’t see anything out of the norm, except this line this.theme = response.data; is unnecessary.

First thing’s first, if you check Vue Devtools Vuex tab do you see the updated state?

Next, how do you get the data in your component? I don’t see any getters defined in your store


#7

Q: (First thing’s first, if you check Vue Devtools Vuex tab do you see the updated state?)
A: from dev tools / vuex i can see the proper collection navbtns containing submenu set, after creating the new submenu button vuex is treating it as a root menu button item not a submenu ? i have to refresh the page to get the proper setup in the collection. and i can see the update on my app also, but as a main button on the main navigation not as a submenu in a dropdown list.

Q: how do you get the data in your component
A: i have a top navigation component that loads the collection and map it like this

    mounted () {

      this.$store.dispatch('getNavbtns');

    },


    computed:{

      ...mapState([

           'navbtns'

        ]),

    },

when a user creates the new submenu button i trigger this action of the store to add the btn to DB and update the store

this is the updated store as i have it on my App after a lot of changes

import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';

Vue.use(Vuex, axios);

export const store = new Vuex.Store({

    state:{

        navbtns : [], // top navigation btns
    
    },

    mutations: {

        SET_NAVBTNS (state,btns){

            state.navbtns = btns;

        },

        NEW_NAVBTNS (state,newbtn){

            state.navbtns.push(newbtn);

        },

        NEW_SUBMENU (state,submenu){

            state.navbtns.push(submenu);

        },

    },

    actions: {

        getNavbtns: function({commit}){

            axios.get('/admin/designer/api/navbtns')
                
                .then(response => {

                    this.navbtns = response.data;

                    let btns = response.data;

                    commit('SET_NAVBTNS', btns)

                })

            .catch( error => {

                  Event.$emit('requestAlertDanger');

            })
        
        },

        addNewSubmenu : function(context, id){

            axios.post('api/submenu/store', {

                    navigation_id   : id,
                    name            : //...
                    sort            : //...
                    icon            : //...
                    link_type       : //...

                })

                .then(function (response) {

                    let submenu = response.data;

                    commit('NEW_SUBMENU', submenu); // this is not getting the submenus properly

                })

                .catch(function (error) {

                    console.log(error);

                    Event.$emit('requestAlertDanger');

            });

        },
    },
 })
``

#8

I don’t see this mutation in store: context.commit(‘NEW_SUBMENU’, submenu);


#9

OOOPS,


        NEW_SUBMENU (state,submenu){

            state.navbtns.push(submenu);

        },

I will update the code on the previous post also


#10
NEW_SUBMENU (state,submenu){
  state.navbtns.push(submenu);
}

This would be why you see it on the main navbtns array. You are pushing it to the root level. You need to find the related main nav (by ID would likely make sense) and push it to its subnav.

NEW_SUBMENU (state,submenu){
  // find related main nav index by ID
  // then push the new subnav
  state.navbtns[index].push(submenu);
}

#11

i’m already passing the ID of the submenu from the axios ajax call along with the context on the same store file

        addNewSubmenu : function(context, id){ // this is the ID

            axios.post('api/submenu/store', {

                    navigation_id   : id,
                    name            : 'Unnamed',
                    sort            : 4,
                    icon            : 'fas fa-home',
                })

                .then(function (response) {

                    let submenu = response.data;

                    commit('NEW_SUBMENU', submenu);


                })

                .catch(function (error) {

                    console.log(error);

                    Event.$emit('requestAlertDanger');

            });

        },

can you please show the proper code with the ID or index as you want me to write??? that would be greate


#12

You are passing an ID, but that’s for your endpoint, not the store. You have 2 options

  1. Replace the entire array with your response. This could have unintended consequences though which I’m not aware of.

So instead of pushing the subnav, you would replace the whole thing.

let newNav = response.data;
commit('SET_NAVBTNS', newNav);
  1. Pass the ID along with the commit so you can find which nav to updated
commit('NEW_SUBMENU', { id, submenu });

then your mutation would be something like

NEW_SUBMENU (state,{ id, submenu }){
  let index = state.navbtns.findIndex(el => el.id = id);
  state.navbtns[index].submenu.push(submenu);
}

So assuming id = 3, it should return 0 as the index (as it’s the first object in the array) which then allows you to push the new submenu to the submenu's array.


#13

Thanx man, you gave me a lot of things to work with, … i will contact your if i have further clarifications.

All the best