I have created a local API with Laravel. I have tried use Postman to run this API which is return me data, but when i using Axios in NativesScript Javascript file, it doesn't return the data nor error message.
I have tried use Async and Await in the function but still return nothing.
import axios from 'axios'
export default class Service {
async testing(){
await axios.get('https://app.app/api/testing')
.then(res => {
console.log(res.data);
})
.catch(function(error) {
console.log(error);
});
}
}
I expect the output is 1, but it come out with "", and i found out that it never go to the API (I have put debug point, it no trigger.), but the Postman work just fine (same url), it trigger the debug point and it does return me value 1.
Thank you.
async/await should be wrapped inside try/catch block.
try {
const result = await axios.get('https://app.app/api/testing');
console.log(result)
} catch(err) {
console.log(err);
}
Related
Basically I am starting with Jest and I want to know with this tool if an API returns a response with status code 200. I have searched many ways to do it on the internet but none of them worked for me and I kept getting errors.
Could someone give me a hand on that?
For example, make a Rick & Morty API call with either Axios or Fetch and see if it returns a 200 status code:
https://rickandmortyapi.com/api/character
I tried something like this:
File mock.js
const getMovies = async () => {
try {
let res = await axios.get('https://rickandmortyapi.com/api/character')
return res
}
catch(error) {
console.log('Error! D:')
return error.response
}
}
export default getMovies;
File mock.test.js
import axios from 'axios';
import getMovies from './mock.js';
jest.mock('./mock.js');
test('should return a 200 status code', async () => {
const res = await getMovies()
expect(res.status).toBe(200)
})
And it shows me the following:
I want to know when my aplication receves a correct answer (a 200 status code) from the API to start to work normally.
Try it
axios.get('/foo')
.catch(function (error) {
if (error.response) {
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
}
});
my fetch is stuck in pending when I query a fastapi endpoint in local dev.
followed this blog and a few others - https://damaris-goebel.medium.com/promise-pending-60482132574d
Using this fetch code (having simplified it drastically just to get a simple solution working)
function fastapiRequest(path) {
return fetch(`${path}`)
.then((response) => {
return response;
}
);
into a constant variable i.e.,
const xxxx = fastapiRequest(
`http://0.0.0.0:8008/xcascasc/Dexaa/Emo.json?Magic=Dexxaa&emotion=expressions`
);
Ideally I want to use UseSWR to do this as I'm using next.js, but first of all, just need it to work :)
A postman query like this works fine to return a value
curl --location --request GET 'http://0.0.0.0:8008/xcaxc/dexxa/emo.json?analysis=statistical&substance=dexxa&emo=powa' \
--header 'x_token: 13wdxaxacxasdc1'
the value is left like this in console.log
data show here? Promise {<pending>}
With the initial response being
Response {type: 'cors', url: 'url', redirected: false, status: 200, ok: true, …}
Update based on answers.
Using each of the proposed answers, I am still not getting the data returned appropriately. i.e.,
function fastApiRequest(path) {
console.log("really begins here");
return fetch(`${path}`, { mode: 'cors' })
.then((response) => {
console.log('response', response);
return response.json();
})
.catch((err) => {
throw err;
});
}
async function test() {
console.log('begins');
return await fastApiRequest(
`http://0.0.0.0:8008/xxxx/dex/adea.json?deaed=adedea&adee=deaed&adeada=adeeda`
);
}
const ansa = test();
Is giving a response of pending at the moment.
The backend is built with fastapi, with these CORS, I'm wondering if I need to give it more time to get the data? (postman works fine :/)
def get_db():
try:
db = SessionLocal()
yield db
finally:
db.close()
origins = [
"http://moodmap.app",
"http://localhost:3000/dashboard/MoodMap",
"http://localhost:3000",
"http://localhost",
"http://localhost:8080",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
max_age=3600,
)
I am running the fastapi code in a docker container as well btw
As per Documentation
The Response object, in turn, does not directly contain the actual JSON response body but is instead a representation of the entire HTTP response. So, to extract the JSON body content from the Response object, we use the json() method, which returns a second promise that resolves with the result of parsing the response body text as JSON.
.json() is an async method (it returns a Promise itself), so you have to assign the parsed value in the next .then(). So your code can be changed like this.
function fastApiRequest(path) {
let res;
fetch(`${path}`)
.then((response) => response.json())
.then((data) => (res = data))
.then(() => console.log(res));
return res;
}
response = fastApiRequest('https://proton.api.atomicassets.io/atomicassets/v1/accounts?limit=10');
console.log('response')
If you want to use async/await approach, below is the code.
async function fastApiRequest(path) {
try {
const response = await fetch(path);
const data = await response.json();
return data;
} catch (error) {
console.error(error);
}
}
async function test() {
console.log(await fastApiRequest('https://proton.api.atomicassets.io/atomicassets/v1/accounts?limit=10'))
}
test()
first you need to parse the response into json if it's a json API.
function fastapiRequest(path) {
return fetch(`${path}`)
.then((response) => {
return response.json();
});
}
you need to 'await' for the rsponse
you need to write the below code in an async function
const xxxx = await fastapiRequest(
`http://0.0.0.0:8008/xcascasc/Dexaa/Emo.json?Magic=Dexxaa&emotion=expressions`
);
When you make an http request using fetch in javascript it will return a Promise, it's not stuck it's just need to be resloved, you can resolve it just like the above code with async await, or you can use the .then(() => { /* code... */ }) function, you can also use .catch(() => { /* handle error... */ }) function to handle errors.
In Your curl you use x_token as header variable, if it's required you need to pass a header with your path too. All other answers are valid too.
I'm using firebase in my reactjs+typescript project. I want to write a document in firebase and I'm using setDoc to do this job.
import { doc, setDoc } from 'firebase/firestore';
setDoc(doc(database, `path`), objData)
When you check the function return it says Promise<...>. But, how am I supposed to use then() catch() promise handlers if I don't know what the promise returns when it fullfil/reject?
I'm not very familiar with Firebase but after looking around it seems the return is just going to be whether or not the setDoc() was successful. So the .then() would mean yes and the .catch() would mean no. So really all you would want is something like this
import { doc, setDoc } from 'firebase/firestore';
setDoc(doc(database, `path`), objData)
.then(() => {
console.log("Successful")})
.catch((error) => {
console.log(`Unsuccessful returned error ${error}`)});
Again I am not fully sure about the exact values returned as I could not find much but if there is a result value given you would place it in the .then((result) => {console.log(result)}).
The firebase documentation suggest using await, so here you have a complete example of error handling with await and cleanup with finally.
import { doc, setDoc } from 'firebase/firestore';
async function run() {
try {
await setDoc(doc(database, `path`), objData)
} catch (e) {
console.error(e); // handle your error here
} finally {
console.log('Cleanup here'); // cleanup, always executed
}
}
run();
In Typescript, you don't need to specify the promise return type precisely. Here's an example of how to use promise handlers with setDoc:
import { doc, setDoc } from 'firebase/firestore';
setDoc(doc(database, `path`), objData)
.then((data) => {console.log('data', data);})
.catch((err) => {console.log('err', err);})
I found some odd behavior. I'm making a handler function in Angular that calls a Firebase Cloud Function that writes to Firestore. I'm using the emulator.
app.component.ts
wordRequest(word: string, l2Language: L2Language, requestOrigin: string) {
const buildWordObject = httpsCallableFromURL(this.functions, 'http://localhost:5001/my-app/us-central1/buildWordObject');
buildWordObject({
word: word,
l2Language: l2Language,
requestOrigin: requestOrigin
})
.then((result) => {
console.log(result.data);
if (result.data === null) {
console.log("Success! Word object written to database.");
}
})
.catch((error) => {
console.error(error);
});
}
index.js
export const buildWordObject = functions.https.onCall((data, context) => {
...does various stuff here
setDoc(doc(firestore, 'Dictionaries/' + longLanguage + '/Words', word), wordObject)
.then(() => {
console.log("Finished writing word object to Firestore database: " + word);
return 37
})
.catch((error: any) => {
console.error(error);
return error
});
return 38
});
This logs Finished writing word object to Firestore database: luck in the emulator console and logs 38 in the Angular console.
If I comment out return 38 the emulator log is the same but in the Angular console I see:
Success! Word object written to database.
Either way the data is written to the Firestore emulator.
A successful database write returns null to the Angular handler function that called it. I don't see Success! for a few seconds so it's clearly doing something async.
If I comment out return 37 and return error then everything runs without errors. Usually when I write a Firebase Cloud Function without a return statement it throws an error in the log.
What I find odd is that the return to the Angular handler is always null, never 37. The console.log message writes to the emulator log but the return 37 statement never executes. You can't return anything but null back to the calling function.
I tried putting .finally(() => { return 37 }); at the end but I never got 37 back.
I am building a react-native app, and I am starting to implement a more robust and sophisticated error-handling system, specifically for handling server errors when making http requests. Here is a basic example of how I am currently making http requests in my app.
I have a 'client.js' file which is essentially just a wrapper around axios. I have a 'get' method that looks like this:
const get = async (endpoint, config = {}) => {
try {
const result = await axios.get(domain + endpoint, config);
return result;
} catch (error) {
throw new Error(error.message);
}
};
Then, I have a file for each api endpoint that I need to access. For example, I have a 'posts.js' file, and in that file I have a 'getPosts' method:
const getPosts = async (userID, page, pageSize) => {
try {
const response = await client.get(
`${endpoint}?userID=${userID}&page=${page}&pageSize=${pageSize}`
);
return response.data;
} catch (error) {
throw new Error(error.message);
}
};
And then finally, in the component that is calling getPosts, I have a function that looks something like this:
const loadPosts = async () => {
try {
const response = await getPosts();
// do something with the response from the server
} catch (error) {
// display an error message to the client
}
}
Obviously this is a very simple example of what a request might look like, but this is the basic structure that I use throughout my app. The problem I am having is that it seems very repetitive and messy to have to wrap almost all of my functions in a try/catch block, and then basically raise an error object until I get to the function that is actually going to handle the error. Is there some sort of 'design method' for error handling that simplifies and centralizes this process? Perhaps something similar to an express-middleware when creating a node server? Or is this a standard way to handle errors in javascript?
Thank you to anyone who can help!
As you are using axios as the http library here, so you can take a look at axios interceptor in order to hook the response and do something with that before passing it to the consumer. This will help you to respond to errors raised from once cental place.
axios.interceptors.response.use((response) => {
return response;
}, function(error) {
// do what you want to do with the error.
return Promise.reject(error)
});
Or with ES5 syntax
axios.interceptors.response.use(function (response) {
// Do something with response data
return response;
}, function (error) {
// Not 200 Ok
// Do something with response error
return Promise.reject(error);
});
I am trying to use axios-auth-refresh library installed by npm. I stucked at problem i can't resolve. According to documentation i made code like this:
const refreshAuthLogic = (failedRequest) => {
let tokenData = JSON.parse(localStorage.getItem("REACT_TOKEN_AUTH"));
if (tokenData) {
return axios
.post(`${process.env.REACT_APP_API_URI}/Login/refresh-token`, {
departmentId: tokenData.departmentId,
jwtToken: tokenData.jwtToken,
userId: tokenData.userId,
})
.then((response) => {
console.log(response);
localStorage.setItem("REACT_TOKEN_AUTH", JSON.stringify(response.data));
failedRequest.response.config.headers["Authorization"] =
"Bearer " + response.data.jwtToken;
return Promise.resolve();
})
.catch((err) => {
console.log(`refreshed failed`);
logout();
return Promise.reject(err);
});
} else {
logout();
}
};
createAuthRefreshInterceptor(axios, refreshAuthLogic, {
statusCodes: [401],
});
Everything works almost perfect but catch never fire up so i can't logout user when refresh token expired. I get answer from api with 401 code but even if i try to put simple console log in .catch() nothing happen.
I have no idea what am i doing wrong? any ideas how to add logout() function to that code that will work?
Thanks to Sangam Rajpara, I've found a solution. You need to create a separate instance of axios.
const requestToken = axios.create();
Then use interceptors for the created instance. You can read about them on the axios page. Something like this:
requestToken.interceptors.response.use(
(res) => res,
(err) => {
// your log out action
logout();
return err;
}
);
Then, in your code instead of axios, use the instance that you created:
requestToken
.post(`${process.env.REACT_APP_API_URI}/Login/refresh-token`, {
departmentId: tokenData.departmentId, ...
You don't really need that "if" logic anymore