vue.js how to call multiple url data in single axios - laravel

i am trying get multiple url data in single axios. i already added single url but i want to add another url.
i tired this but it giving null object error
{{ BusinessCount }}
{{ UserCount }}
import axios from "axios";
export default {
data() {
return {
businesslists: [],
Userslist: [],
};
},
async asyncData({ $axios }) {
let { datas } = await $axios.$get("/Userslist");
return {
Userslist: datas,
};
},
computed: {
UserCount() {
return Object.keys(this.Userslist).length;
},
},
async asyncData({ $axios }) {
let { data } = await $axios.$get("/Businessregisterlist");
return {
businesslists: data,
};
},
computed: {
BusinessCount() {
return Object.keys(this.businesslists).length;
},
},
};
i want to show like this
<p>{{ BusinessCount }}</p>
<p>{{ UserCount }}</p>
1st url
/Businessregisterlist
2nd url
/Userlist
my code
<template>
<p>{{ BusinessCount }}</p>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
BusinessCounts: [],
};
},
async asyncData({ $axios }) {
let { datad } = await $axios.$get("/Businessregisterlist");
return {
BusinessCounts: datad,
};
},
computed: {
BusinessCount() {
return Object.keys(this.BusinessCounts).length;
},
},
};
</script>

In your tried code you define the asyncData function 2 times. That's incorrect. But you can make 2 calls to the server in a single asyncData function.
Try:
async asyncData({ $axios }) {
let { datad } = await $axios.$get("/Businessregisterlist");
let { dataUsers } = await $axios.$get("/Userslist");
return {
Businesslist: datad,
Userslist: dataUsers
};
},
computed: {
BusinessCount() {
return Object.keys(this.Businesslist).length;
},
UserCount() {
return Object.keys(this.Userslist).length;
},
},
Make sure you correctly define the Businesslist and Userslist in the data section.

Related

Error in mounted hook (Promise/async): "TypeError: Cannot read properties of undefined (reading 'SET_POST')"

This is the store.js where am consuming the API. I wanted to get the data from the API and display it when loaded. but at the moment am getting two errors
Error in mounted hook (Promise/async): "TypeError: Cannot read properties of undefined (reading 'SET_POST')"
TypeError: Cannot read properties of undefined (reading 'SET_POST')
<template>
<div v-if="!isDataLoaded">
Loading ...Please wait
</div>
<div v-else="isDataLoaded">
</div>
</template>
<script>
import { mapGetters } from 'vuex';
export default{
data: () => ({
isDataLoaded: false,
}),
computed:{
...mapGetters([
"GET_POST",
]),
},
methods: {
post() {
return this.$store.getters.GET_POST;
}
},
async mounted() {
await this.$store.actions.SET_POST
this.isDataLoaded = true
}
}
</script>
store.js file
`
import Vue from "vue";
import Vuex from 'vuex';
import axios from "axios";
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
form: [],
post: [],
twoChunkPost: []
},
getters: {
GET_POST: state => {
return state.post;
}
},
mutations: {
SET_POST(state, post) {
state.post = post;
},
}
actions: {
SET_POST: async ({ commit }) => {
const options = {
headers: {
"Content-Type": "application/json"
}
};
let { data } = await axios.get(
"/api/post",
options
);
if (data.meta.code === 200) {
let postArray = data.data.post;
let chunkSize = 2;
commit("SET_POST", postArray);
let chunkedArray = chunk(postArray, chunkSize);
commit("SET_CHUNKED_POST", chunkedArray);
}
},
}
});
`

Vue 3 components not awaiting for state to be loaded

I am having some trouble using fetch in vuex to build state before rendering my page's components.
Here is the page component code:
async beforeCreate() {
await this.$store.dispatch('projects/getProjects');
},
And this is the state code it's dispatching:
async getProjects(context: any, parms: any) {
context.commit("loadingStatus", true, { root: true });
console.log("1");
await fetch(`${process.env.VUE_APP_API}/projects?`, {
method: "get",
headers: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
})
.then((response) => {
console.log("2");
if (!response.ok) {
throw new Error(response.status.toString());
} else {
return response.json();
}
})
.catch((error) => {
// todo: tratamento de erros na UI
console.error("There was an error!", error);
})
.then((data) => {
context.commit("setProjects", { data });
console.log("3");
// sets the active project based on local storage
if (
localStorage.getItem(
`activeProjectId_${context.rootState.auth.operator.accountId}`
)
) {
console.log("setting project to storage");
context.dispatch("selectProject", {
projectId: localStorage.getItem(
`activeProjectId_${context.rootState.auth.operator.accountId}`
),
});
} else {
//or based on the first item in the list
console.log("setting project to default");
if (data.length > 0) {
context.dispatch("selectProject", {
projectId: data[0].id,
});
}
}
context.commit("loadingStatus", false, { root: true });
});
},
async selectProject(context: any, parms: any) {
console.log("4");
context.commit("loadingStatus", true, { root: true });
const pjt = context.state.projects.filter(
(project: any) => project.id === parms.projectId
);
if (pjt.length > 0) {
console.log("Project found");
await context.commit("setActiveProject", pjt[0]);
} else if (context.state.projects.length > 0) {
console.log("Project not found setting first on the list");
await context.commit("setActiveProject", context.state.projects[0]);
} else {
await context.commit("resetActiveProject");
}
await context.commit("loadingStatus", false, { root: true });
},
I've added this console.log (1, 2, 3, 4) to help me debug what's going on.
Right after console.logging "1", it starts to mount the components. And I only get logs 2, 3 and 4 after all components have been loaded.
How can I make it so that my components will only load after the whole process is done (i.e. after I log "4") ?
If your beforeCreate hook (or any client hooks) contains async code, Vue will NOT wait to it then render and mount the component.
The right choice here should be showing a loader when your data is fetching from the server. It will provide better UX:
<template>
<div v-if="!data"> Loading... </div>
<div v-else> Put all your logic with data here </div>
</template>
<script>
export default {
data() {
return {
data: null
}
},
async beforeCreate() {
this.data = await this.$store.dispatch('projects/getProjects');
},
}
</script>

Print data from axios

I try to print data from axios.
In controller:
public function index()
{
return User::latest();
}
In user.vue:
export default {
data() {
return {
users: {},
}
},
methods: {
loadUsers() {
axios.get('/user').then(({ data }) => (this.users = user))
console.log(user)
},
},
created() {
this.loadUsers()
},
}
And table:
<tr v-for="user in users.data" :key="user.id">
<td>{{user.email}}</td>
</tr>
Web
Route::get('/user','UserController#index');
console.log prints the data, but in table no data.
axios call async call so make a promise call .then() after fetching data it will call and you can make usable the fetched data.
import axios from "axios";
const API_URL = "http://192.168.1.26:8000";
export class BaseStatus_Service {
getBaseStatus_list() {
const url = `${API_URL}/api/baf1/baseStatus`;
return axios.get(url).then(response => response.data);
}
const serviceUtil = new BaseStatus_Service();
serviceUtil.getBaseStatus_list().then((results)=>{
console.log(results);
})

Unable to fetch data from API (Resource blocked by client) in Vuex

I'm trying to fetch some data from my API using vuex + axios, but the action give me a "Network Error" (ERR_BLOCKED_BY_CLIENT).
when i was using json-server it works fine, but it doesn't work with my API even with 'Allow-Access-Control-Origin': '*'
actions
const actions = {
async fetchSearch({ commit, state }) {
let res
try {
res = await axios(`http://localhost:8000/api/advertisements/search?column=title&per_page=${state.params.per_page}&search_input=${state.params.query.toLowerCase()}&page=${state.params.page}`, {
method: 'GET',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
}
})
} catch(err) {
console.log(err)
}
commit('clearProducts')
commit('setProducts', res.data)
},
setGlobalParams({ commit }, obj) {
commit('clearParams')
commit('setParams', obj)
}
}
component
<script>
/* Vuex import */
import { mapActions } from 'vuex'
export default {
name: 'base-search-component',
data() {
return {
query_obj: {
page: 1,
per_page: 8,
query: ''
}
}
},
methods: {
...mapActions([
'fetchSearch',
'setGlobalParams'
]),
fetchData() {
if (this.query_obj.query === '') {
return
} else {
this.setGlobalParams(this.query_obj)
this.fetchSearch()
this.$router.push({ name: 'search', params: { query_obj: this.query_obj } })
}
}
}
}
</script>
Assuming your cors issue was properly resolved the reason you cannot access the data is that it is being set before the axios promise is being resolved.
Change:
async fetchSearch({ commit, state }) {
let res
try {
res = await axios(`http://localhost:8000/api/advertisements/search?column=title&per_page=${state.params.per_page}&search_input=${state.params.query.toLowerCase()}&page=${state.params.page}`, {
method: 'GET',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
}
})
} catch(err) {
console.log(err)
}
commit('clearProducts')
commit('setProducts', res.data)
}
to:
async fetchSearch({ commit, state }) {
await axios(`http://localhost:8000/api/advertisements/search?column=title&per_page=${state.params.per_page}&search_input=${state.params.query.toLowerCase()}&page=${state.params.page}`, {
method: 'GET',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
}
}).then(function (response) {
commit('clearProducts')
commit('setProducts', response.data)
}).catch(err) {
console.log(err)
}
}
Further you should use mapState. Assuming setProducts is setting a state object like products this would look like:
<script>
/* Vuex import */
import { mapState, mapActions } from 'vuex'
export default {
name: 'base-search-component',
data() {
return {
query_obj: {
page: 1,
per_page: 8,
query: ''
}
}
},
computed: {
mapState([
'products'
])
},
methods: {
...mapActions([
'fetchSearch',
'setGlobalParams'
]),
fetchData() {
if (this.query_obj.query === '') {
return
} else {
this.setGlobalParams(this.query_obj)
this.fetchSearch()
this.$router.push({ name: 'search', params: { query_obj: this.query_obj } })
}
}
}
}
</script>
Now you can refrence this.products in JS or products in your template.

Get component to wait for asynchronous data before rendering

I am calling an endpoint to bring back an object, which does fetch the data, however not fast enough for the component to grab the data and render. Instead, the component renders with blank values where there should be data.
If I break point the code on creation, then continue maybe a second later, the text correctly renders.
How do I implement it to not render until the data is back?
My API call:
checkScenarioType: function () {
this.$http.get('ScenariosVue/GetScenarioTypeFromParticipant/' + this.ParticipantId).then(response => {
// get body data
this.ScenarioType = response.body.value;
if (this.ScenarioType.timeConstraint) {
store.commit('switchConstraint');
}
}, response => {
// error callback
});
}
The component having the issues:
var questionArea = Vue.component('questionarea', {
props: ["scenariotype"],
data: function () {
return ({
position: "",
vehicleType: ""
});
},
methods: {
transformValuesForDisplay: function () {
switch (this.scenariotype.perspective) {
case 1: {
this.position = "Driver";
this.vehicleType = "Autonomous";
break;
}
case 2: {
this.position = "Passenger";
this.vehicleType = "Manually Driven";
break;
}
case 3: {
this.position = "Driver";
this.vehicleType = "Manually Driven";
break;
}
}
}
},
beforeMount() {
this.transformValuesForDisplay();
},
template:
`<h1>You are the {{ this.position }}! What should the {{ this.vehicleType }} car do?</h1>`
});
In cases like there's asynchronous loading of data, we typically use a simple v-if to hide the element until the data is present.
The template would be like:
<h1 v-if="position">You are the {{ position }}! What should the {{ vehicleType }} car do?</h1>
Notice the use of this in the template is unnecessary.
Also, in your case, instead of the beforeMount() hook, you would add a (deep/immediate) watch to the prop, to pick up changes when it is loaded externally:
watch: {
scenariotype: {
handler: function(newValue) {
this.transformValuesForDisplay();
},
deep: true,
immediate: true
}
},
Full demo below.
Vue.component('questionarea', {
props: ["scenariotype"],
data: function () {
return ({
position: "",
vehicleType: ""
});
},
methods: {
transformValuesForDisplay: function () {
switch (this.scenariotype.perspective) {
case 1: {
this.position = "Driver";
this.vehicleType = "Autonomous";
break;
}
case 2: {
this.position = "Passenger";
this.vehicleType = "Manually Driven";
break;
}
case 3: {
this.position = "Driver";
this.vehicleType = "Manually Driven";
break;
}
}
}
},
watch: {
scenariotype: {
handler: function(newValue) {
this.transformValuesForDisplay();
},
deep: true,
immediate: true
}
},
template:
`<h1 v-if="position">You are the {{ position }}! What should the {{ vehicleType }} car do?</h1>`
});
new Vue({
el: '#app',
data: {
ScenarioType: {perspective: null}
},
methods: {
checkScenarioType: function () {
this.$http.get('https://reqres.in/api/users/2').then(response => {
// get body data
this.ScenarioType.perspective = response.body.data.id; // for testing purposes only
}, response => {
// error callback
});
}
},
mounted: function() {
this.checkScenarioType();
}
})
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vue-resource"></script>
<div id="app">
<p>Notice while it is null, the h1 is hidden: {{ ScenarioType }}</p>
<br>
<questionarea :scenariotype="ScenarioType"></questionarea>
</div>

Resources