Response Header not accessible in JS - javascript

I am using React + Redux on the front end and Spring for the backend. The reponse header contains Authorization header when viewed on browser and in postman but not when trying to access in javascript. I have added the photos showing response headers in network tab and on console tab. And also i am using axios for the request.
auth.js
...
export const authInit = (data) => {
return dispatch => {
dispatch(authInitStart());
axios.post('/login', data)
.then(response => {
if(response.status === 200){
const param = {
'Authorization': response.headers.Authorization
};
console.log("Authorization----" + JSON.stringify(response));
console.log("Param----" + JSON.stringify(param));
localStorage.setItem('Authorization', param['Authorization']);
dispatch(authInitSuccess(param['Authorization']));
}else{
dispatch(authInitFail('Request failed'));
}
}).catch(err => {
dispatch(authInitFail('Network error'));
});
};
};
...
param object is empty here
What can be the issue?

Access-Control-Expose-Headers: Authorization
response.headers.get('Authorization')
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers

Related

React Native Screen wont re-render after fetching data and setting state using HTTP request

I am using the react-native google API to request calendar data via HTTP request using axios.
After the user clicks a login button the function calendarData is initiated and successfully pulls the data and I use setCalendarEvents to set the state of my page to this response data.
I expected this to re-render the screen and display the data but it is not...How can I initiate a page refresh after this data is received from the HTTP request without a manual re-render?
STATE
const [calendarEvents, setCalendarEvents] = useState([]);
calendarData function RUNS AFTER LOG IN BUTTON IS PRESSED BY USER
const calendarData = async function signInWithGoogleAsync() {
try {
const result = await Google.logInAsync({
androidClientId: `['CLIENT ID]`,
iosClientId: `['CLIENT ID']`,
scopes: [
"profile",
"email",
"https://www.googleapis.com/auth/calendar",
"https://www.googleapis.com/auth/calendar.events",
],
});
if (result.type === "success") {
axios({
//HTTP GET REQUEST FOR DATA
method: "get",
baseURL: "https://www.googleapis.com/calendar/v3/calendars/['USER CALENDAR]/events?key=['API KEY']",
headers: {
Authorization: "Bearer " + result.accessToken,
Accept: "application/json",
},
})
.then((response) => {
const responseDataArray = [];
//RESPONSE DATA
response.data["items"].map((event) => {
if (typeof event["start"].dateTime !== undefined) {
responseDataArray.push(event);
}
//SET STATE TO RETREIVED AND FILTERED DATA STORED IN responseDataArray
setCalendarEvents(responseDataArray);
});
})
//CATCH ERRORS
.catch((error) => console.log(error));
} else {
return { cancelled: true };
}
} catch (e) {
return { error: true };
}
};
WHERE DATA SHOULD BE RENDERED ON THE SCREEN AFTER SUCCESSFUL GET
return (
<View>
{calendarEvents.map((event) => {
<View>{event}</View>
}
}
</View>
)
EXAMPLE OF RESPONSE DATA ITEM
I am looking to filter out "start":{"dateTime":"2021-04-16T17:30:00-04:00"} if it exists
{"kind":"calendar#event","etag":"\"3237003518996000\"","id":"7t1q67ai1p7t586peevd7s9mhg","status":"confirmed","htmlLink":"https://www.google.com/calendar/event?eid=N3QxcTY3YWkxcDd0NTg2cGVldmQ3czltaGcgbWF0dEBoZWFydGhkaXNwbGF5LmNvbQ","created":"2021-04-14T16:45:34.000Z","updated":"2021-04-15T15:49:19.498Z","summary":"customer journey beta buddies","creator":{"email":"meilin#hearthdisplay.com"},"organizer":{"email":"meilin#hearthdisplay.com"},"start":{"dateTime":"2021-04-16T17:30:00-04:00"},"end":{"dateTime":"2021-04-16T18:30:00-04:00"},"iCalUID":"7t1q67ai1p7t586peevd7s9mhg#google.com","sequence":0,"attendees":[{"email":"meilin#hearthdisplay.com","organizer":true,"responseStatus":"accepted"},{"email":"matt#hearthdisplay.com","self":true,"optional":true,"responseStatus":"accepted"},{"email":"susie#hearthdisplay.com","responseStatus":"accepted"},{"email":"nathalie#hearthdisplay.com","responseStatus":"accepted"}],"hangoutLink":"https://meet.google.com/xyb-qhpb-uej","conferenceData":{"entryPoints":[{"entryPointType":"video","uri":"https://meet.google.com/xyb-qhpb-uej","label":"meet.google.com/xyb-qhpb-uej"},{"entryPointType":"more","uri":"https://tel.meet/xyb-qhpb-uej?pin=3822838393771","pin":"3822838393771"},{"regionCode":"US","entryPointType":"phone","uri":"tel:+1-818-514-5197","label":"+1 818-514-5197","pin":"222000933"}],"conferenceSolution":{"key":{"type":"hangoutsMeet"},"name":"Google Meet","iconUri":"https://fonts.gstatic.com/s/i/productlogos/meet_2020q4/v6/web-512dp/logo_meet_2020q4_color_2x_web_512dp.png"},"conferenceId":"xyb-qhpb-uej","signature":"AGirE/Jmi4pFHkq0kcqgRyOuAR2r"},"reminders":{"useDefault":true},"eventType":"default"}
Maybe try with this, add conditional rendering :
return ({
calendarEvents.length>0 &&
calendarEvents?.map(...your code)
})

Azure Function axios POST empty Response

I am trying to make an axios call in my React frontend to get some information from the backend to access some information. When I log the response on the server, I see the required information, but in the axios call, I get data = "" for some reason.
ReactJS Axios call
await axios
.post(url, {
token: this.props.authUser.idToken.rawIdToken,
blob_path: blobPath,
container: container
},
config
)
.then((response) => {
if(response.data == ""){
console.log("nada");
debugger;
}
callback(response);
})
.catch((error) => {
debugger;
callback(error);
});
Azure Server Response Code
exit = (result) => {
console.log("---------- RESULT ------------");
console.log(result);
console.log("------ END RESULT ------------");
context.res = {
status: 200 /* Defaults to 200 */,
body: result,
headers: { 'Content-Type': 'application/json' },
};
context.done();
};
The response on the backend
The response on the frontend
EDIT: Axios is sending double requests and the old request's response gets ignored.

Receving "500 Internal Server Error" on Post Request to Firebase-Cloud-Function Endpoint

I'm trying to make a POST request using axios to my firebase cloud-function on form submit in react app. But I get '500' error everytime I make a request with an html-page response This app works best with javascriot enabled.
Latest Update:
It looks like there is no issue with cloud function
code. Rather more of a react-component issue. I used Postman to send
the POST request with header prop Content-Type set to application/json
and sending body in raw format {"email": "example_email"} and got
expected response from the cloud function. But when sent the request from
react component above, I get an html file response saying the app
works best with javascript enabled
I've tried setting Content-Type to both Application/json and multipart/form-data as I suspected it to be an issue but still got no luck.
Following is my code for cloud function and react submit form:
Cloud Function
const functions = require('firebase-functions');
const cors = require('cors')({ origin: true })
const runThisFunc1 = require(./libs/runThisFunc1);
const runThisFunc2 = require(./libs/runThisFunc2);
exports.wizardFunc = functions.https.onRequest((request, response) => {
cors(request, response, () => {
let email = request.body.email;
try {
return runThisFunc1(email)
.then(data => {
console.log("Word Done by 1!");
return runThisFunc2(data);
})
.then(res => {
console.log("Word Done by 2!");
return response.status(200).send("Success");
})
.catch(err => {
console.error("Error: ", err.code);
return response.status(500).end();
});
}catch(err) {
return response.status(400).end();
}
});
});
React-Form-Component Snippet
import axios from 'axios'
...
handleSubmit = e => {
e.preventDefault()
const { email } = this.state
axios({
method: 'post',
url: `${process.env.REACT_APP_CLOUD_FUNCTION_ENDPOINT}`,
data: { email: email },
config: {
headers: {
'Content-Type': 'multipart/form-data'
}
}
})
.then(res => {
//do something with reponse here
})
.catch(error => {
console.error(error)
})
}
...
Is there something wrong I am doing in the code or the request config is wrong?

How to get response headers for 303 request using Axios reactjs

I am using below code
const configureAjaxClient = () => {
let csrf_token = '';
const instance = axios.create({
baseURL: '/abc',
timeout: 300000,
paramsSerializer: (params) => {
return qs.stringify(params, { arrayFormat: 'brackets' });
},
});
instance.interceptors.request.use((config) => {
config.headers['X-CSRF-Token'] = csrf_token;
if (config.data) {
config.data = qs.stringify(config.data);
}
return config;
});
instance.interceptors.response.use((response) => {
if (response.data) {
return Promise.reject(response);
}
return response;
}, (error) => {
return Promise.reject(error);
});
return instance;
};
export default configureAjaxClient;
when my request is 303 is redirect to location header in response, and error function is called with below
errorError:Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:87)
And in error I get error.response as undefined.
How will I get response headers, and I want the redirect to another route.
Please help
I am using latest Axios and reactjs
You can't. Axios is a wrapper around XMLHttpRequest which handles redirect responses transparently and has no option to change that.
If you were to switch to fetch, then you could use a request object to specify that redirections were not followed automatically.
This header was missing in the request which my server is checking that its Ajax request or not
// Headers
// This header is required to inform server that its an Ajax request
instance.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
As of right now, you can:
const response = axios('your303endpoint')
.catch(data => data.response.headers)
.then(headers => console.log(headers))

Check Axios request url before sending

API requests are failing because the URL generated by Axios is incorrect due to my config. I know what the request url is suppose to look like, so I want to see the request url Axios generates.
I can point Axios to my local server and see the requests there, but I want to debug this on the client. I want to play with the config, and see how the requests change. Is there a way to output the request url from Axios before or after sending?
// param format
{ address: 'Vancouver', key: GOOGLE_API_KEY }
// Geocode sample
https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&key=YOUR_API_KEY
_request = async (...args) => {
const { outputFormat, params } = args
const instance = axios.create({
baseURL: `https://maps.googleapis.com`,
})
const response = await instance.get('/maps/api/geocode/${outputFormat}?', {
params,
})
// I want to see the url generated by Axios so I can debug the issue
console.log(response)
}
I am within the Expo, React Native environment.
Working example using fetch:
const url = `https://maps.googleapis.com/maps/api/geocode/json?address=vancouver&key=${GOOGLE_API_KEY}`
fetch(url)
.then((response) => response.json())
.then((data) => {
console.log(data)
})
.catch(function(error) {
console.log(error)
})
Solution used:
_request = async (obj) => {
const { outputFormat, params } = obj
const instance = axios.create({
baseURL: `https://maps.googleapis.com`,
})
instance.interceptors.request.use(function (config) {
console.log(config)
return config
}, function (error) {
return Promise.reject(error)
})
const response = await instance.get(`/maps/api/geocode/${outputFormat}`, {
params,
})
}
You can turn on debug mode and look at the network tab as mentioned in the other answer, or you can intercept axios and console.log or do whatever you want with the request before it's sent:
axios.interceptors.request.use(function (config) {
// Do something before request is sent
console.log(config)
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
You can just use axios#getUri([config]) (source) to perform the same logic as the request. It merges the configurations (e.g. the given config and the instance configuration), merges the url with the baseURL, and appends any params using the paramSerializer.

Categories

Resources