Why can't I access the response headers below? They should be accessible on the response object, which I am unpacking into the data and headers variables. I am thinking it might be trying to access the headers on the Promise, instead of the resolved response object.
getDomains({ commit, state }) {
return new Promise(async (resolve, reject) => {
try {
const { data, headers } = await axios.get(`http://wordpress.api/wp-json/sslchkr/v1/author/${state.user.id}/domain`, {
headers: {
Authorization: `Bearer ${state.user.token}`
}
})
commit('SET_DOMAINS', data, headers)
resolve(data)
} catch(e) {
reject(e)
}
})
},
I solved this riddle by passing in the response object to SET_DOMAINS, it only takes one argument.
SET_DOMAINS(state, res) {
state.domains.domains = res.data
state.domains.totalDomains = res.headers['x-wp-total']
state.domains.totalPages = res.headers['x-wp-totalpages']
}
Related
i'm trying to send a request to the backend which uses headers, please how can i add the headers
this is my script tag
<script>
import axios from "axios";
export default {
data: () => ({
fullName: "",
streetAddress1: ""
}),
created() {
//user is not authorized
if (localStorage.getItem("token") === null) {
this.$router.push("/login");
}
},
methods: {
async onAddAddress() {
const token = localStorage.getItem("token");
headers: {
"Content-Type": "application/json",
Authorization: "Bearer" + token,
"x-access-token": token
}
try {
let data = {
fullName: this.fullName,
streetAddress: this.streetAddress1
};
const response = axios
.post("http://localhost:5000/api/addresses", data)
.then(res => {
console.log(res);
});
console.log(response);
} catch (error) {
console.error("error >>", error);
}
}
}
}
this code gives me an error, please how can i go about this
There are a few problems with your code. For instance you do not define headers as a variable and you do not add it to your axios request as a third argument. I think you need something like this:
async onAddAddress() {
const token = localStorage.getItem("token");
/// define headers variable
const headers = {
"Content-Type": "application/json",
Authorization: "Bearer" + token,
"x-access-token": token
};
let data = {
fullName: this.fullName,
streetAddress: this.streetAddress1
};
try {
/// config as the third argument.
conts result = await axios.post("http://localhost:5000/api/addresses", data, { headers });
console.log(result);
}
catch (error) {
console.error("error >>", error)
}
}
For async/await to work, you need to add await in front of the axios call.
Hope this helps.
I making a multi-upload file form.
Upon user cancellation, once the corresponding axios call get cancelled using cancel(), I having a weird behaviour. My axios call get caught inside the then() whereas it should be caught inside of catch(). The response inside of then() returns undefined.
I am having a hard time figuring if I did something wrong on the front-end part, I think my call is may be missing some headers or maybe it's on the backend part ?
const payload = { file, objectId: articleId, contentType: 'article' };
const source = axios.CancelToken.source();
// callback to execute at progression
const onUploadProgress = (event) => {
const percentage = Math.round((100 * event.loaded) / event.total);
this.handleFileUploadProgression(file, {
percentage,
status: 'pending',
cancelSource: source,
});
};
attachmentService
.create(payload, { onUploadProgress, cancelToken: source.token })
.then((response) => {
// cancelation response ends up here with a `undefined` response content
})
.catch((error) => {
console.log(error);
// canceled request do not reads as errors down here
if (axios.isCancel(error)) {
console.log('axios request cancelled', error);
}
});
the service itself is defined below
export const attachmentService = {
create(payload, requestOptions) {
// FormData cannot be decamelized inside an interceptor so it's done before, here.
const formData = new FormData();
Object.entries(payload).forEach(([key, value]) =>
formData.append(decamelize(key), value),
);
return api
.post(resource, formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
...requestOptions,
})
.then((response) => {
console.log(response, 'cancelled request answered here as `undefined`');
return response.data;
})
.catch((error) => {
// not caught here (earlier)
return error.data;
});
},
};
cancellation is called upon a file object doing
file.cancelSource.cancel('Request was cancelled by the user');
As suggested by #estus-flask in a comment, the issue is that I was catching the error inside of the service (too early). Thank you!
export const articleService = {
create(payload, requestOptions) {
// FormData cannot be decamelized inside an interceptor so it's done before, here.
const formData = new FormData();
Object.entries(payload).forEach(([key, value]) =>
formData.append(decamelize(key), value),
);
return api.post(resource, formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
...requestOptions,
});
},
};
My Question is similar to this which doesn't have an answer. I tried to search many other places but still don't have an answer.
I'm trying to download file using Axios in VueJs as a blob:
return new Promise((resolve, reject) => {
Axios.get(`${fileDownloadUrl}`,
{ responseType: 'blob' } // Blob doesn't handle errors
).then(response => {
let byteData = response.data
var blob = new Blob([byteData], {type: response.headers['content-type']})
let fileName = _.split(response.headers['content-disposition'], '=')
FileSaver.saveAs(blob, fileName[1])
resolve(fileName[1])
},
error => {
console.log(error.response.data) // returns Blob - error message from service is not handled
reject(error.response.data)
}
)
I removed the { responseType: 'blob' } from the above code and tried again, I get the error message now but the file downloaded doesn't have any content, it's a blank data.
How do I download the file and handle the error response returned by the service?
Using vue-resource solved this issue. Although it will be retiring in future releases, I couldn't find a better way to do it as Axios was not able to handle it.
Following is the code:
main.js
import VueResource from 'vue-resource'
Vue.use(VueResource)
service.js
return new Promise((resolve, reject) => {
VueResource.http.get(`${fileDownloadUrl}`,
{ responseType: 'blob' }
).then(response => {
methods.downloadFile(response, cid)
resolve(cid)
}, error => {
reject(error)
})
})
Hope this helps.
import axios from "axios";
// It is needed to handle when your response is not Blob (for example when response is json format)
axios.interceptors.response.use(
response => {
return response;
},
error => {
if (
error.request.responseType === 'blob' &&
error.response.data instanceof Blob &&
error.response.data.type &&
error.response.data.type.toLowerCase().indexOf('json') != -1
) {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = () => {
error.response.data = JSON.parse(reader.result);
resolve(Promise.reject(error));
};
reader.onerror = () => {
reject(error);
};
reader.readAsText(error.response.data);
});
}
return Promise.reject(error);
}
);
// Now you can get response in both Blob and json format
axios.get(
url,
{
responseType: 'blob'
}
).then(response => {
// Your Code
}).catch((error) => {
// Your Code
// You can get error in json format
});
May I know is it possible to use post instead of get in the following request
Axios.get(${fileDownloadUrl},
{ responseType: 'blob' }
I am new to react-native. I am trying to pass the authorization token through a header in the GET method. But I am getting an unauthorized error.
I have already tried this code "Using an authorization header with Fetch in React Native" not working for me and also with XMLHttpRequest()
But the API works fine in postman, Java(core) and Android.
Do we have any special implementation in react-native to pass headers?
Could anyone can help me with this?
My code: Changed the server name.
getData() {
var data = null;
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("GET", "https://xyz-test-server.server.com/api/v3/users/details/");
xhr.setRequestHeader("Authorization", "Basic cC5qYWltdXJ1Z2FuLm1jYUBnbWFpbC5jb206MTIzNDU2");
xhr.setRequestHeader("User-Agent", "PostmanRuntime/7.17.1");
xhr.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded; charset=ISO-8859-1");
xhr.setRequestHeader("Accept", "*/*");
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("Postman-Token", "d8ae56bf-1926-44e4-9e94-23223234,93a110a2-ee8e-42d5-9f7b-45645ddsfg45");
xhr.setRequestHeader("Accept-Encoding", "gzip, deflate");
xhr.setRequestHeader("Connection", "keep-alive");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.send(data);
}
Fetch method:
async _getProtectedQuote() {
fetch('https://xyz-test-server.server.com/api/v3/users/details/', {
method: 'GET',
headers: new Headers({
'Authorization': 'Basic cC5qYWltdXJ1Z2FuLm1jYUBnbWFpbC5jb206MTIzNDU2',
'Content-Type': 'application/x-www-form-urlencoded'
}),
}).then(responseJson => {
alert(JSON.stringify(responseJson));
console.log(responseJson);
});
}
You can try interceptor for pass token into header.
Put all requests in one service file name service.js then import Interceptor from '../interceptor';
make one interceptor.js file and write below code in file.
import axios from 'axios';
axios.interceptors.request.use(async (config) => {
if (config.method !== 'OPTIONS') {
config.headers.Authorization = 'Basic cC5qYWltdXJ1Z2FuLm1jYUBnbWFpbC5jb206MTIzNDU2';
}
return config;
}, function (error) {
// Do something with request error
console.log('how are you error: ', error);
return promise.reject(error);
});
axios.interceptors.response.use(
(response) => {
return response
},
async (error) => {
// const originalRequest = error.config
console.log("error in interceptors=============>", error);
if (error.response.status === 500) {
alert(error.response.data.message);
NavigationService.navigate('Login');
} else {
return Promise.reject(error)
}
}
)
export default axios;
When api calls header will pass through by interceptor automatically.
Fetch Api converts all headers into lower-case. We need to do case-insensitive server side parsing.
I'm currently calling a JSON api to set an auth token which I'll just be storing in the AsyncStorage to persist between app life so a user doesn't have to log in every single time.
I'm currently setting that token like so:
fetch(url, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(this.state)
})
.then( resp => {
return resp.json();
})
.then( async (data) => {
if ('error' in data) {
this.setState({
error: data.error,
password: ''
})
this.secondTextInput.focus();
}
if ('access_token' in data) {
try {
await AsyncStorage.setItem('access_token', data.access_token);
} catch (error) {
return error;
}
this.props.navigation.navigate('Main');
}
})
.catch(
error => {
console.error(error)
return error;
}
);
If I then call AsyncStorage.getItem('access_token') After killing the app or reloading it I'm winding up with this output:
{
"_40":0,
"_65":0,
"_55":null,
"_72":null
}
If I then call AsyncStorage.getItem('access_token') Before killing the app or reloading it I'm winding up with the correct access token. I've double checked the code and I'm not using AsyncStorage.setItem('access_token') anywhere else.
This is how I'm retrieving my token:
componentDidMount() {
console.warn('Mounting');
try {
let token = AsyncStorage.getItem('access_token');
console.warn(token);
if(token !== null) {
console.error(token);
}
} catch (error) {}
AsyncStorage.getItem() is a asynchronous action just like setItem(), so you need to wait until the Promise has been resolved before logging.
Edit
Tip: if you see some strange output like that it is always related to a Promise which is not yet resolved or rejected
I've solved my issue by using #dentemm's recommendation of creating an async function.
async _getToken() {
try {
var token = await AsyncStorage.getItem('access_token');
return token;
} catch(e) {
console.error(e);
}
}
componentDidMount() {
let token = null;
this._getToken()
.then( rsp => {
fetch(global.url + '/api/auth/refresh', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + rsp
}
})
.then(rsp => {
return rsp.json();
})
.then(data => {
if('access_token' in data) {
try {
AsyncStorage.setItem('access_token', data.access_token);
} catch (error) {
return error;
}
this.props.navigation.navigate('Main');
}
})
.catch( error => {
return error;
})
});
}
This way I can get my token from the storage then run my refresh function to get an updated token to use for future requests.