Get url from axios.get response in react native - react-native

I have a simple like this in one of my component:
componentDidMount() {
axios
.get(
API_URL +
"oauth2/authorize?client_id=" +
API_CLIENT_ID +
"&response_type=token"
)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
}
however, i would like to parse the callback url which is from imgur Oauth2 app:
https://example.com/oauthcallback#access_token=ACCESS_TOKEN&token_type=Bearer&expires_in=3600
but cant seem to access it, i could only see response.status which is 200, response.header, ect.. how to get the url ?

Response Schema of axios request
{
// `data` is the response that was provided by the server
data: {},
}
try this
response.data.url

You can parse your request's response url like this:
response.request.responseURL

Related

axios interceptor blocking api calls in redux saga

I have a react native project in which I'm calling some API's using redux-saga mechanism. Now when I added response interceptor for axios my saga api's are not working anymore. Does any knows how I can fix this?
here is the code for my axios instance class and response interceptor
const getLoggedInUser = async () => {
const savedUser = JSON.parse(
await getDataFromAsyncStorage(APP_CONSTANTS.SAVED_USER)
)
if (savedUser?.user_id != null) {
return savedUser
}
return null
}
const baseapi = axios.create({
baseURL: APP_CONSTANTS.BASE_URL,
headers: {},
})
baseapi.interceptors.request.use(
async (config) => {
const token = await getLoggedInUser()
const userId = token?.user_id
const authToken = token?.token
if (token) {
baseapi.defaults.headers.common['userId'] = token
baseapi.defaults.headers.common['token'] = authToken
}
return config
},
(error) => {
return Promise.reject(error)
}
)
// Response interceptor for API calls
baseapi.interceptors.response.use(
(response) => {
return response
},
async function (error) {
const originalRequest = error.config
if (error.response.status === 403 /* && !originalRequest._retry */) {
return baseapi(originalRequest)
}
return Promise.reject(error)
}
)
This is my saga class code and it fails directly when I add a response interceptor
function* getTopicList(action) {
try {
yield put({type: ACTION_TYPES.START_TOPIC_LIST})
const {payload} = action
const res = yield call(getAllTopicsOfBatch, payload)
if (res?.status == APP_CONSTANTS.SUCCESS_STATUS) {
yield put({
type: ACTION_TYPES.SET_TOPIC_LIST,
payload: {data: res?.data?.topics},
})
} else {
alert('OOPS Something went wrong! Please try again')
yield put({
type: ACTION_TYPES.ERROR_TOPIC_LIST,
payload: 'Something Went Wrong Please Try Again',
})
}
} catch (error) {
console.log('RESPONES error', error)
alert('OOPS Something went wrong! Please try again')
yield put({
type: ACTION_TYPES.ERROR_TOPIC_LIST,
payload: 'Something Went Wrong Please Try Again',
})
}
}
The code looks mostly fine, the only two things I found that are likely causing problems are:
In the request interceptors you are likely wrongly passing the whole token as userId instead of userId
baseapi.defaults.headers.common['userId'] = token // 'token' should be 'userId'
In the response interceptors error handler, you are not guaranteed to have 'response' property on error.
if (error.response.status === 403) // use error?.response
If neither of these things will fix your problem my guess is you have a problem in your endpoint and so you should examine the response errors you get to guide you.

Call Nextjs API from within Netlify function

I got a serverless Netlify function like this:
exports.handler = async function(event, context) {
return {
statusCode: 200,
body: JSON.stringify({message: "Hello World"})
};
}
When called by this url <site-name>/.netlify/functions/helloworld
I do get the message {"message":"Hello World"}
I also got a pages/api/mailingList.js Nextjs API endpoint:
const axios = require('axios');
export default async function handler(req, res) {
//console.log(req.query.mail);
if (req.method === "PUT") {
axios
.put(
"https://api.sendgrid.com/v3/marketing/contacts",
{
contacts: [{ email: `${req.query.mail}` }],
list_ids: [process.env.SENDGRID_MAILING_LIST_ID],
},
{
headers: {
"content-type": "application/json",
Authorization: `Bearer ${process.env.SENDGRID_API_KEY}`,
},
}
)
.then((result) => {
res.status(200).send({
message:
"Your email has been successfully added to the mailing list. Welcome 👋",
});
})
.catch((err) => {
res.status(500).send({
message:
"Oups, there was a problem with your subscription, please try again or contact us",
});
console.error(err);
});
}
}
This mailing list API endpoint, do work when using curl from the terminal with PUT as the method:
curl -X PUT -d mail=helloworld#gmail.com https://netlify.app/api/mailingList
The API endpoint also work from the URL (/api/mailingList?mail=helloworld#gmail.com) when removing the if (req.method === "PUT") { part from the mailingList.js
However, I am NOT able to get the API endpoint to be called from within the Netlify function.
(Preferably the mailingList API should be possible to call multiple times with different mailing list IDs from the Netlify function helloworld.js based on different logic /api/mailingList?mail=helloworld#gmail.com&listid=xxx)
To get the API endpoint to be called at all, from the function, I have tried adding a axios call from the helloworld.js to mailingList.js like this
const axios = require('axios');
exports.handler = async function(event, context) {
const mail = "helloworld#gmail.com";
// add to mailinglist
axios
.put("/api/mailingList?mail="+mail)
.then((result) => {
if (result.status === 200) {
toast.success(result.data.message);
}
})
.catch((err) => {
console.log(err);
});
}
This result in the following error from the browser: error decoding lambda response: invalid status code returned from lambda: 0
(I do not get any error msg from the Netlify log, either helloworld.js or mailingList.js)
Clearly, there is something wrong with how I call the mailigList.js from helloworld.js. Would greatly appreciate if some one could give me some advice and show me what I am doing wrong.
How can I call the API endpoint (mailigList.js) from within the Netlify function helloworld.js? (Preferably multiple times with different mailing list IDs: /api/mailingList?mail=helloworld#gmail.com&listid=xxx)
Found the solution in this article: https://travishorn.com/netlify-lambda-functions-from-scratch-1186f61c659e
const axios = require('axios');
const mail = "helloworld#gmail.com";
exports.handler = (event, context, callback) => {
axios.put("https://<domain>.netlify.app/api/mailingList?mail="+mail)
.then((res) => {
callback(null, {
statusCode: 200,
body: res.data.title,
});
})
.catch((err) => {
callback(err);
});
};

401 Unauthorized error in Express API post request

I am trying to develop the logic for a POST route handler in Express. I put the following together:
const headers = {
"Authorization":"TS Token asdfghjk-asdf-4567-fghjkl; tid=onfido-token";
"content-type": "application/json"
};
const params = {
"policy_request_id": "onfido_applicantandtoken"
};
app.get("/get_stuff", (req, res) => {
axios
.post("https://third/party/api", {
headers,
params
})
.then(function (response) {
res.json(response.data);
})
.catch(function (error) {
res.json("Error occured!");
});
}
});
I keep getting a 401 Unauthorized for the above. On Postman it works, but with the logic above I get a 401 Unauthorized, specifically in the logs I would get Header 'Authorization' not found or Could not parse authorization header. So I am unclear as to what could be going on with the header.
A lot of posts talk about req.headers, but my req.headers does not have the Authorization token and content-type in there, it has some other token that the API I am trying to connect to I assume needs to reach out to another API.
I have refactored it to look like this:
app.get("/get_stuff", (req, res) => {
axios
.post("https://third/party/api", params, headers)
.then(function (response) {
res.json(response.data);
})
.catch(function (error) {
res.json("Error occured!");
});
}
});
And I am still getting the same exact error.
To be clear the params is not something that gets passed into the URL on Postman, but rather the body of the postman request.
I was able to get it to successfully connect by declaring a global axios default like so:
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
as documented here:
https://www.npmjs.com/package/axios#user-content-config-defaults

Local Netlify function server gives strange response instead of FaunaDB data

I am trying to build a simple web-app with Vue and a FaunaDB. When trying to fetch data from the DB i get the following error:
localhost/:1 Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
When i print the response from the Netlify function server this is what i get:
Here is the code from the vue-page that tries to get the data:
created() {
EventService.readAll()
.then(response => {
this.events = response.data
})
}
This is the EventService Modul:
const readAllDates = () => {
console.log("hey")
return fetch('/.netlify/functions/read-all-dates').then((response) => {
console.log(response)
return response.json()
})
}
export default {
readAll: readAllDates
}
and this is my read-all-dates.js:
import faunadb from 'faunadb'
const q = faunadb.query
const client = new faunadb.Client({
secret: process.env.FAUNADB_SECRET
})
exports.handler = (event, context, callback) => {
console.log("Function `read-all-dates` invoked")
return client.query(q.Paginate(q.Match(q.Ref("indexes/all_dates"))))
.then((response) => {
const dateRefs = response.data
console.log("Todo refs", dateRefs)
console.log(`${dateRefs.length} todos found`)
const getAllDateDataQuery = dateRefs.map((ref) => {
return q.Get(ref)
})
// then query the refs
return client.query(getAllDateDataQuery).then((ret) => {
return callback(null, {
statusCode: 200,
body: JSON.stringify(ret)
})
})
}).catch((error) => {
console.log("error", error)
return callback(null, {
statusCode: 400,
body: JSON.stringify(error)
})
})
}
What am i doing wrong?
Turns out it was vue-router which stopped the netlify proxy from directing the request to the right endoint. There seems no good way around this in dev:
https://forum.vuejs.org/t/devserver-proxy-not-working-when-using-router-on-history-mode/54720
The error you posted is one that it's worth getting familiar with!
localhost/:1 Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
Effectively this is caused when you try to parse something as JSON, but it's not actually JSON. The < is a tell-tale sign that the request response was probably HTML instead of JSON. The next step in debugging is to look at the XHR request itself in the browser debugging "Network" panel.
In my experience, one of the most common reasons for this error is a routing problem, which is triggering a 404 response route serving HTML instead of your expected function handler.

sending back api data to vue in express returns empty object

I'm trying to send some data back from my express app using the following in my app.js this data comes from a 3rd party api and I want to send it back to my front end application. I am able to see the content in my express api but it doesn't seem to deliver a result to my front end?? anyone have any ideas as to why I'm getting log below in the console.
I suspect it has to do with some async or timeout issue with the express app but I haven't been able to fix the issue myself.
function getFish(){
axios.get('https://www.fishwatch.gov/api/species')
.then(function (response) {
console.log(response)
return response
})
.catch(function (error) {
console.log(error);
})
}
app.get('/getFish', async(req,res) =>{
let fish = await getFish()
res.json({fishes: fish})
})
when I try to log the data in my app, I only get an empty object
{}
here is my vue code to log the value's returned by my express api.
created:function(){
this.fetchFish()
},
methods: {
fetchFish(){
fetch('http://localhost:3000/getFish')
.then((response) => {
return response.json();
})
.then((data) => {
console.log(data);
});
}
}
You need to return the axios promise in your server's getFish function or the /getFish route won't be awaiting anything:
function getFish(){
// New `return` statement
return axios.get('https://www.fishwatch.gov/api/species')
.then(function (response) {
console.log(response)
return response
})
.catch(function (error) {
console.log(error);
})
}