Vue + Axios with sessionStorage - vue.js

Goal: Initially load posts using the Wordpress Rest API via Axios once in a Vue View, and only once during a session of visiting the Vue website.
Current Result: I currently fetch the results successfully and set them in sessionStorage. They display correctly. I want to know/learn if I am accomplishing this correctly and have the process optimized in the best way possible. I've looked up documentation and I think I have it down.
Current Code:
<script>
import Hero from "#/components/Hero.vue";
import axios from "axios";
export default {
name: "About",
components: {
Hero,
},
data: function() {
return {
eatery: [],
};
},
created() {
axios
.get("//localhost:81/wp-json/wp/v2/posts?_embed&per_page=5&categories=2")
.then((response) => {
sessionStorage.setItem("eatery", JSON.stringify(response.data));
})
.catch((error) => {
window.alert(error);
});
},
mounted() {
if (sessionStorage.getItem("eatery")) {
this.eatery = JSON.parse(sessionStorage.getItem("eatery"));
}
},
};
</script>

I would check whether it's in the storage before trying to load it. In your case, it would look like this:
export default {
name: "About",
components: {
Hero,
},
data: function() {
return {
eatery: [],
};
},
loadEatery() {
axios
.get("//localhost:81/wp-json/wp/v2/posts?_embed&per_page=5&categories=2")
.then((response) => {
sessionStorage.setItem("eatery", JSON.stringify(response.data));
return response.data;
})
.catch((error) => {
console.error(error); // for debugging maybe
});
},
mounted() {
if (sessionStorage.getItem("eatery")) {
this.eatery = JSON.parse(sessionStorage.getItem("eatery"));
} else {
loadEatery().then(data => this.eatery = data);
}
},
};

Related

Nuxt js Router Push Not Working After Delete

I've created a simple CRUD with Nuxt. Data is provided by Lumen. I got a problem with the DELETE, data is deleted but Nuxt does not redirect to the other page.
Here is my script:
<script>
export default {
name: 'EmployeePage',
data() {
return {
fields: ['name','email','image','address'],
emplyees:[],
}
},
mounted() {
this.$axios.get('/employee').then(response => {
this.pegawais = response.data.data
}).catch(error => {
console.log(error.response.data)
})
},
methods: {
async delete(id) {
await this.$axios.delete(`/employee/${id}`).then(response => {
this.$router.push({ name: 'employee' }) <-----this redirect not working
})
}
}
}
</script>
I want Nuxt to redirect to the employee page that display all the data after the deletion.
You should not mix async/await and .then. Use the first approach, that way you will not have the .then callback hell and it will be cleaner overall.
Like this
<script>
export default {
name: 'EmployeePage',
data() {
return {
fields: ['name', 'email', 'image', 'address'],
emplyees: [],
}
},
async mounted() {
try {
const response = await this.$axios.get('/employee')
this.pegawais = response.data.data
} catch (error) {
console.log(error.response.data)
}
},
methods: {
async delete(id) {
await this.$axios.delete(`/employee/${id}`)
await this.$router.push({ name: 'employee' })
},
},
}
</script>
await this.$router.push does not require an await but it's a Promise too, so I'm writing it like that in case you need to call something else afterwards.
this.$axios.$get('/employee') can also be used if you want to remove a .data aka this.pegawais = response.data as shown here.

How to access query string in nuxtjs and pass it to data

I want to access query strings from url in nuxtjs page.
this is the page url with query strings -
http://localhost:3000/en-IN/atrsps/results/?pickupairport=Dubai&dropoffpoint=Bur%20Dubai,%20DU,%20United%20Arab%20Emirates&pickupdate=06%2F06%2F2021%2013%3A27
this is the my page script part
<script>
import axios from 'axios'
export default {
data() {
return {
cars: [],
loading: false,
disabled: true,
pickupairport: null,
dropoffpoint: null
}
},
asyncData({ route }) {
console.log(route.query)
},
computed: {
url() {
return `https://api.testdomain.com/V2/transfers/carlist?startpoint=${this.pickupairport}&endpoint=${this.dropoffpoint}&pickupdate=2021-07-01&pickuptime=14:55`
},
},
async created() {
await this.fetchData()
},
methods: {
async fetchData() {
this.loading = true //the loading begin
const res = await axios.get(this.url)
this.cars = res.data.response
this.loading = false
},
carsearch($state) {
setTimeout(() => {
axios
.get(this.url)
.then((res) => {
if (res.data.response.length > 1) {
res.data.response.forEach((item) => this.cars.push(item))
$state.loaded()
} else {
$state.complete()
}
})
.catch((err) => {
console.log(err)
})
}, 1000)
},
},
}
</script>
I want to pass pickupairport and dropoffpoint value from url to pickupairport & dropoffpoint in data.
in console, i can see this data
{
pickupairport: 'Dubai',
dropoffpoint: 'Bur Dubai, DU, United Arab Emirates',
pickupdate: '06/06/2021 13:27'
}
from the template you can access to it from $route object like $route.query and from the vue instance you can write this.$route.query
also you can check the $route object from vue dev tools. check out the picture below:
to pass the queries to data object you can just write:
data() {
return {
pickupairport: this.$route.query.pickupairport,
}
}
but you might not need to store the query in data object since you have access to $route object either from template or anywhere in your script

Is there a way to detect query changes using Vue-Router and successfully get new data?

I am simply making an asynchronous request to get data about a MLB player but am failing to get new data by manually changing the query parameters in the URL. When I use watch, the from and the to are the same for some reason upon debugging with Vue dev tools. However, all works well when I manually click a link to navigate routes as the from and the to correctly represent the from and the to routes.
PitcherForm.vue
export default {
name: "PitcherForm",
components: {
PlayerForm,
},
watch: {
$route() {
this.handleSubmit({ firstName: this.$route.query.firstName, lastName: this.$route.query.lastName });
}
},
methods: {
handleSubmit: function(formValues) {
// this.$store.dispatch("fetchPlayer", { formValues, router: this.$router, player: "pitching" });
this.$store
.dispatch("fetchPlayer", { formValues, player: "pitching" })
.then((promiseObject) => {
console.log(promiseObject)
this.$router.push({
// name: 'PitcherData',
path: "pitching/player",
query: {
firstName: promiseObject.firstName,
lastName: promiseObject.lastName,
},
});
})
.catch((error) => {
console.log(error);
});
},
},
//store.js
import Vue from 'vue';
import Vuex from 'vuex';
import VuexPersist from 'vuex-persist';
import axios from 'axios';
Vue.use(Vuex);
// VuexPersist stuff
const vuexLocalStorage = new VuexPersist({
key: 'vuex',
storage: window.localStorage,
});
export const store = new Vuex.Store({
plugins: [vuexLocalStorage.plugin],
state: {
playerStats: []
},
// mutations, getters, excluded for convenience
actions: {
fetchPlayer({ commit }, data) {
return new Promise((resolve) => {
let firstName = data.formValues.firstName.replace(/\s/g, "").toLowerCase();
let lastName = data.formValues.lastName.replace(/\s/g, "").toLowerCase();
axios.get(`http://localhost:5000/${data.player}/player`,
{
params: {
first: firstName.charAt(0).toUpperCase() + firstName.slice(1),
last: lastName.charAt(0).toUpperCase() + lastName.slice(1),
},
}).then(response => {
commit('setPlayers', response.data);
}).catch((error) => {
console.log(error);
});
resolve({firstName, lastName});
});
}
}
});

Pass the url of the current domain in axios VueJS

I am trying to pass the url of the domain where I am to pass it in axios. Here is my current hard url:
import axios from 'axios';
export default {
name: 'cart',
components: {},
data() {
return {
cart: '',
timer: '',
baseUrl: 'http://prestashop_1_6.local/modules/analyticsvuejs/php/cart.php',
}
},
methods: {
getCarts() {
axios
.get(this.baseUrl, {
params: {
action: 'cart'
}
})
.then(response => {
this.cart = response.data;
console.log(this.cart);
}, (error) => {
console.log(error);
}
)
},
},
created() {
this.getCarts();
this.timer = setInterval(this.getCarts, 5000)
},
}
and I'm trying to create a variable to dynamically pass it to all my components
I am looking to replace 'http: //prestashop_1_6.local/' with a dynamic variable.
Thank you for your help.
1) Create a separate file with a const containing this base url.
2) export this const
3) use it wherever you want
// consts.js
export const BASE_URL = 'http://prestashop_1_6.local';
// Any file that consume it.
import {BASE_URL} from './consts';
data() {
return {
url: `${BASE_URL}/something/something-else`
};
}

Correct way to do a redirect after posting through axios in a vuex store

I am using nuxtjs, axios and vuex to post from a form component to post my data to my backend.
When posted I'd like to redirect to the view record screen and populate it with the returned information using the ID to navigate there
so my path might be /cases/14325 (if 14325 is the id returned once created)
What is the correct way to do this please
I have the following code in my vuex store
export const state = () => ({
cases: []
})
// *** MUTATIONS ***
export const mutations = {
add(state, newCase ) {
state.cases.push(newCase)
},
}
// *** ACTIONS ***
export const actions = {
addCase(context, newCase) {
const createdCase = {
...newCase
}
axios.post("http", createdCase)
.then(result => {
context.commit('add', {...createdCase, id: result.data.name})
})
.catch(e => console.log(e));
},
}
In my component I have the following
import { mapMutations, mapGetters, mapActions } from 'vuex'
export default {
data () {
return {
newCase: {
caseName: '',
summary: '',
status: 'live',
},
}
},
methods: {
...mapActions([
'addCase'
]),
onSubmit() {
// Save the post
this.$store.dispatch('addCase').then(path => {
this.$router.redirect(path)
}).catch((err) => {
console.log(err)
})
},
}
}
</script>
How do i return the new id from my store please and replace cases/1 with '/cases/' + new id?
Thanks for the help as always
Maybe is will be enough when you improve your action this way:
addCase(context, newCase) {
return new Promise ((resolve, reject) => {
const createdCase = {...newCase}
axios.post('http', createdCase).then(result => {
context.commit('add', {...createdCase, id: result.data.name})
resolve(/*path*/)
}).catch(e => {
console.log(e)
reject(/*reason*/)
})
})
}
And then you use it this way:
this.$store.dispatch('addCase', context).then(path => {
this.$router.redirect(path)
})