Vue send request when declared params changed from empty string - javascript

In my app I'm sending a request to my backend app from which I get a response with id like { 'id': '12345'}. I saves this id as loadId inside data, here:
export default {
name: 'SyncProducts',
data() {
return {
loadId: '',
Now I want to send another POST fetchSyncedProductsResultRequest when this data loadId change from empty. How to do so?
Below my code:
imports.js
const createApparelMagicProductsRequest = (self, products) => {
const jwtToken = self.$store.state.idToken;
console.log(products)
console.log()
const payload = JSON.stringify({ product_codes: products['product_codes'].split(',') })
return axios
.post(`/api/v1/imports/products_batches`, payload,{
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(response => response.data['id'])
};
const fetchSyncedProductsResultRequest = (token, id) => {
return axios
.get(`/api/v1/imports/products_batches`, {
params: { id: id },
headers: {
Authorization: `Bearer ${token}`,
}
})
.then(response => {
return response.data['result']
})
};
sync_products.vue
<script>
import {
fetchSyncedProductsResultRequest,
createApparelMagicProductsRequest
} from '../../api/imports'
export default {
name: 'SyncProducts',
data() {
return {
styleCodes: [],
fetchedProductSyncResult: [],
loadId: '',
}
},
async mounted() {
await fetchSyncedProductsResultRequest(this, load.id)
this.syncedProductsFetched = true
this.pageChanged(this.currentPage)
},
async mounted() {
const jwtToken = this.$store.state.idToken;
fetchSyncedProductsResultRequest(jwtToken).then(data => {
this.fetchedProductSyncResult = data
})
},
</script>

Use a watcher on loadId that calls fetchSyncedProductsResultRequest() with the new value if it's changed from an empty string to a non-empty string:
export default {
watch: {
loadId(newValue, oldValue) {
if (!oldValue && newValue) {
const jwtToken = this.$store.state.idToken;
fetchSyncedProductsResultRequest(jwtToken, newValue).then(data => {
this.fetchedProductSyncResult = data
});
}
}
}
}
demo

Related

Data variable dont get the response in vuejs 3

I do a get in the api and I can collect their data but when I assign it to a data variable it doesn't get it
data() {
return {
departamento: [],
}
},
setup() {
onMounted(() => {
const token = setToken.getToken();
axios
.get("https://sig-fpto.herokuapp.com/api/departamentos/buscarTodos", {
headers: {
Authorization: `Bearer ${token}`,
},
})
.then((response) => {
console.log(response.data);
this.departamento = response.data
})
.catch((err) => console.log(err.response));
})
You are mixing Vue2 syntax with Vue3. Here is what should work:
setup() {
const departamento = ref([]);
onMounted(() => {
const token = setToken.getToken();
axios
.get("https://sig-fpto.herokuapp.com/api/departamentos/buscarTodos", {
headers: {
Authorization: `Bearer ${token}`,
},
})
.then((response) => {
console.log(response.data);
departamento.value = [...response.data];
})
.catch((err) => console.log(err.response));
})
return {
departamento,
}
}

React : call async method from same file

I am trying to call removeCouponCode method which exist in same file but execution says its not defined i am not sure what is missing here.
any thoughts ?
Below is the file which i am editing & trying to make changes.
not sure what is missing.
please have a look at let me know what is missing
import React, { useState, useEffect, useMemo } from 'react';
import SessionContext from 'react-storefront/session/SessionContext';
import PropTypes from 'prop-types';
import fetch from 'react-storefront/fetch';
import get from 'lodash/get';
import { EventTracking, AnalyticsErrors } from '../analytics/Events';
import Cookies from 'js-cookie';
import constants from '../constants/configs';
import errorHandler from '../constants/apiHelpers/errorHandler';
import Helper from '../constants/helper';
import configs from '../constants/configs';
const { session, actions } = useContext(SessionContext);
const initialState = {
signedIn: false,
cart: {
items: [],
shipping_methods: [],
shippingCountry: null,
shippingMethodCode: null,
freeShipingMethod: null,
freeShippingSelected: false
},
customer: {
store_credit: {},
wishlist: { items_count: 0, items: [] },
offline: true
},
errMsg: ''
};
const initialStatusState = {
cartLoadingStatus: false,
setShippingMethodStatus: false
};
async redemptionCode({ couponCode, ...otherParams }) {
let tempSession = { ...session };
const response = await fetch('/api/cart/redemptionCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ couponCode, ...otherParams })
});
const result = await response.json();
if (response.ok) {
if(get(result, 'cart.prices.discounts', {}) === null){
removeCouponCode(...otherParams); //says undefined removeCouponCode here
}
}
},
async removeCouponCode({ ...otherParams }) {
let tempSession = { ...session };
const response = await fetch('/api/cart/removeCouponCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ ...otherParams })
});
},
You didn’t reference your function and reference your function and try or you can either modify your code as follows by declaring it as a function,
async function removeCouponCode({ ...otherParams }) {
let tempSession = { ...session };
const response = await fetch('/api/cart/removeCouponCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ ...otherParams })
});
}
async function redemptionCode({ couponCode, ...otherParams }) {
let tempSession = { ...session };
const response = await fetch('/api/cart/redemptionCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ couponCode, ...otherParams })
});
const result = await response.json();
if (response.ok) {
if(get(result, 'cart.prices.discounts', {}) === null){
await removeCouponCode(...otherParams);
}
}
}
You did not declare them as function. So you define them either this way
async function redemptionCode({ couponCode, ...otherParams }) {
let tempSession = { ...session };
const response = await fetch('/api/cart/redemptionCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ couponCode, ...otherParams })
});
const result = await response.json();
if (response.ok) {
if(get(result, 'cart.prices.discounts', {}) === null){
removeCouponCode(...otherParams); //says undefined removeCouponCode here
}
}
},
async function removeCouponCode({ ...otherParams }) {
let tempSession = { ...session };
const response = await fetch('/api/cart/removeCouponCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ ...otherParams })
});
},
Or this way
const redemptionCode = async ({ couponCode, ...otherParams }) => {
let tempSession = { ...session };
const response = await fetch('/api/cart/redemptionCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ couponCode, ...otherParams })
});
const result = await response.json();
if (response.ok) {
if(get(result, 'cart.prices.discounts', {}) === null){
removeCouponCode(...otherParams); //says undefined removeCouponCode here
}
}
},
const removeCouponCode = async ({ ...otherParams }) => {
let tempSession = { ...session };
const response = await fetch('/api/cart/removeCouponCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ ...otherParams })
});
},
Both should work!
It seems that you define this function after calling it. I think you should first define it and then call it..and you can use the arrow function.

NextJS: TypeError: Cannot read property 'json' of undefined

I've this code into pages folder on my NextJS environment. It gets data calling an external API Rest, and it's working because the console.log(response); line show me by console the Json API response. The problem I've is that I get this error in browser:
TypeError: Cannot read property 'json' of undefined
Corresponding with this line code:
const data = await res.json();
This is the complete file with the code:
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
fetch(invoicesUrl, params)
.then((response) => {
return response.json();
})
.then((response) => {
console.log(response);
})
.catch((err) => {
console.log(err);
});
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
const res = await getFetch(invoicesUrl, params);
const data = await res.json();
console.log("Data Json: ", data);
return { props: { data } };
};
This is the Json API response that I see by console:
{
account: [
{
id: '7051321',
type: 'probe',
status: 'open',
newAccount: [Object],
lastDate: '2020-07-04',
taxExcluded: [Object],
totalRecover: [Object],
documentLinks: []
},
]
}
Any idea how can I solve it?
Thanks in advance.
UPDATE
Here the code working good:
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
return fetch(invoicesUrl, params);
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
try {
const res = await getFetch(invoicesUrl, params);
const data = await res.json();
console.log("Data JSON: ", data);
return { props: { data } };
} catch (error) {
console.log("Data ERROR: ", error);
}
};
There are a couple of things you have to change.
const getFetch = async (invoicesUrl, params) => {
fetch(invoicesUrl, params)
.then((response) => {
return response.json();
})
.then((response) => {
console.log(response);
return response; // 1. Add this line. You need to return the response.
})
.catch((err) => {
console.log(err);
});
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
const data = await getFetch(invoicesUrl, params);
// const data = await res.json(); 2. Remove this you have already converted to JSON by calling .json in getFetch
console.log("Data Json: ", data); // Make sure this prints the data.
return { props: { data } };
};
You have return statement in wrong place.
When the function is expecting a return. You need to return when the statements are executed not inside the promise then function because it is an async callback function which is not sync with the statement inside getFetchfunction. I hope i have made things clear. Below is the code which will any how return something
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
return fetch(invoicesUrl, params);
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
try{
const res = await getFetch(invoicesUrl, params);
console.log("Data Json: ", res);
}catch(error){
console.log("Data Json: ", error);
}
return { props: { res } };
};

TypeError: Cannot read property 'then' of undefined, React app error when trying to save a playlist

Can't seem to resolve this error.
TypeError
For the function to work the user is supposed to be able to add songs to a 'New Playlist' and then save that playlist.
The app seems to work fine until you click the button to save the playlist at which point all you see is this error.
Trying to access this component:
const clientId = "783dbc97776940e28f307dfc902ad41b";
const redirectUri = "http//localhost:3000/";
let accessToken;
const Spotify = {
getAccessToken() {
if (accessToken) {
return accessToken;
}
// check for access token match
const accessTokenMatch = window.location.href.match(/access_token=([^&]*)/);
const expiresInMatch = window.location.href.match(/expires_in=([^&]*)/);
if (accessTokenMatch && expiresInMatch) {
accessToken = accessTokenMatch[1];
const expiresIn = Number(expiresInMatch[1]);
// This clears the parameters, allowing us to grab a new access token when it expires.
window.setTimeout(() => (accessToken = ""), expiresIn * 1000);
window.history.pushState("Access Token", null, "/");
return accessToken;
} else {
const accessUrl = `https://accounts.spotify.com/authorize?client_id=${clientId}&response_type=token&scope=playlist-modify-public&redirect_uri=${redirectUri}`;
window.location = accessUrl;
}
},
search(term) {
const accessToken = Spotify.getAccessToken();
return fetch(`https://api.spotify.com/v1/search?type=track&q=${term}`, {
headers: {
Authorization: `Bearer ${accessToken}`
}
})
.then(response => {
return response.json();
})
.then(jsonResponse => {
if (!jsonResponse.tracks) {
return [];
}
return jsonResponse.tracks.items.map(track => ({
id: track.id,
name: track.name,
artist: track.artists[0].name,
album: track.album.name,
uri: track.uri
}));
});
},
savePlaylist(name, trackUris) {
if (!name || !trackUris.length) {
return;
}
const accessToken = Spotify.getAccessToken();
const headers = { Authorization: `Bearer ${accessToken}` };
let userId;
return fetch("https://api.spotify.com/v1/me", { headers: headers })
.then(response => response.json())
.then(jsonResponse => {
userId = jsonResponse.id;
return fetch(`https://api.spotify.com/v1/users/${userId}/playlists`, {
headers: headers,
method: "POST",
body: JSON.stringify({ name: name })
})
.then(response => response.json())
.then(jsonResponse => {
const playlistId = jsonResponse.id;
return fetch(
`https://api.spotify.com/v1/users/${userId}/playlists/${playlistId}/tracks`,
{
headers: headers,
method: "POST",
body: JSON.stringify({ uris: trackUris })
}
);
});
});
}
};
export default Spotify;
For use here:
import React from 'react';
import './App.css';
import SearchBar from '../SearchBar/SearchBar';
import SearchResults from '../SearchResults/SearchResults';
import Playlist from '../Playlist/Playlist';
import Spotify from '../../util/Spotify';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
searchResults: [],
playlistName: 'My Playlist',
playlistTracks: []
}
this.addTrack = this.addTrack.bind(this);
this.removeTrack = this.removeTrack.bind(this);
this.updatePlaylistName = this.updatePlaylistName.bind(this);
this.savePlaylist = this.savePlaylist.bind(this);
this.search = this.search.bind(this);
}
addTrack(track) {
if (this.state.playlistTracks.find(savedTrack => savedTrack.id === track.id)) {
return;
}
this.state.playlistTracks.push(track);
this.setState({playlistTracks: this.state.playlistTracks})
}
removeTrack(track) {
this.setState.playlistTracks = this.state.playlistTracks.filter(currentTrack => currentTrack.id !== track.id)
this.setState({playlistTracks: this.state.playlistTracks})
}
updatePlaylistName(name) {
this.setState({playlistName: name});
}
savePlaylist() {
const trackUris = this.state.playlistTracks.map(track => track.uri);
Spotify.savePlaylist(this.state.playlistName, trackUris).then(() => {
this.setState({
playlistName: 'New Playlist',
playlistTracks: []
})
})
}
search(term) {
Spotify.search(term).then(searchResults => {
this.setState({searchResults: searchResults})
})
}
render() {
return (
<div>
<h1>Ja<span className="highlight">mmm</span>ing</h1>
<div className="App">
<SearchBar onSearch={this.search} />
<div className="App-playlist">
<SearchResults searchResults={this.state.searchResults} onAdd={this.addTrack} />
<Playlist playlistName={this.state.playlistName} playlistTracks={this.state.playlistTracks} onRemove={this.removeTrack} onNameChange={this.updatePlaylistName} onSave={this.savePlaylist} />
</div>
</div>
</div>
)
}
}
// if(typeof(App.savePlaylist) == 'undefined') {
// console.log('whoops')
// }
export default App;
Any ideas why?
I'm very new to this and am completely lost as to why this is happening.
You need to return a Promise for when the input is not right:
if (!name || !trackUris.length) {
return Promise.resolve();
};
Also, don't change variables of the state object. Don't do this:
this.state.playlistTracks.push(track);
this.setState({playlistTracks: this.state.playlistTracks})
Instead, do this:
this.setState({playlistTracks: [...this.state.playlistTracks, track]})
In you code when the following if condition is true, you're not returning a promise.
savePlaylist(name, trackUris) {
if (!name || !trackUris.length) {
return;
// What you can do instead
// return Promise.reject();
};
....
...
Simply returning return; will return undefined and trying to access then on it will throw error.

How to store, manage REST API JWT authentication token in vue?

I am a noob, using vue.js and a node auth api, the api works fine and provides the jwt token in the response, my question is how can i use the token in all the requests that follows (using axios), and any best practices for handling the token in the front end is also appreciated.
Thanks
You can use something like that for Your scenario in your vuejs app.
import axios from 'axios'
const API_URL = 'http://localhost:3000'
const securedAxiosInstance = axios.create({
baseURL: API_URL,
withCredentials: true,
headers: {
'Content-Type': 'application/json'
}
})
const plainAxiosInstance = axios.create({
baseURL: API_URL,
withCredentials: true,
headers: {
'Content-Type': 'application/json'
}
})
securedAxiosInstance.interceptors.request.use(config => {
const method = config.method.toUpperCase()
if (method !== 'OPTIONS' && method !== 'GET') {
config.headers = {
...config.headers,
'X-CSRF-TOKEN': localStorage.csrf
}
}
return config
})
securedAxiosInstance.interceptors.response.use(null, error => {
if (
error.response &&
error.response.config &&
error.response.status === 401
) {
return plainAxiosInstance
.post('/refresh', {}, { headers: { 'X-CSRF-TOKEN': localStorage.csrf } })
.then(response => {
localStorage.csrf = response.data.csrf
localStorage.signedIn = true
let retryConfig = error.response.config
retryConfig.headers['X-CSRF-TOKEN'] = localStorage.csrf
return plainAxiosInstance.request(retryConfig)
})
.catch(error => {
delete localStorage.csrf
delete localStorage.signedIn
location.replace('/')
return Promise.reject(error)
})
} else {
return Promise.reject(error)
}
})
export { securedAxiosInstance, plainAxiosInstance }
And in your component you use this to process your request with api
Products.vue
export default {
name: 'products',
data () {
return {
products: [],
newProduct: [],
error: '',
editedProduct: ''
}
},
created () {
if (!localStorage.signedIn) {
this.$router.replace('/')
} else {
this.$http.secured.get('/api/v1/products')
.then(response => { this.products = response.data })
.catch(error => this.setError(error, 'Something went wrong'))
}
},
methods: {
setError (error, text) {
this.error = (error.response && error.response.data && error.response.data.error) || text
},
addProduct () {
const value = this.newProduct
if (!value) {
return
}
this.$http.secured.post('/api/v1/products/', { product: { name: this.newProduct.name } })
.then(response => {
this.products.push(response.data)
this.newProduct = ''
})
.catch(error => this.setError(error, 'Cannot create product'))
},
removeProduct (product) {
this.$http.secured.delete(`/api/v1/products/${product.id}`)
.then(response => {
this.products.splice(this.products.indexOf(product), 1)
})
.catch(error => this.setError(error, 'Cannot delete product'))
},
editProduct (product) {
this.editedproduct = product
},
updateProduct (product) {
this.editedProduct = ''
this.$http.secured.patch(`/api/v1/products/${product.id}`, { product: { title: product.name } })
.catch(error => this.setError(error, 'Cannot update product'))
}
}
}
You can find here a lot of good patterns which I personally use on my projects and how also JWT token handling.
For saving token in a brower, you can use cookie, sessionStorage or localStorate, last one is the most popular now (short explination here).
In a few words, you can create an axion instance and add a token before request sent.
const http = axios.create({
baseURL: process.env.VUE_APP_SERVER_API,
// here you can specify other params
})
http.interceptors.request.use(request => {
// Do something before request is sent
request.headers['Authorization'] = `JWT ${TOKEN_HERE}`
// some logic what to do if toke invalid, etc ...
return request
}, function (error) {
// Do something with request error
return Promise.reject(error)
})

Categories

Resources