Getting the API by the callback function in React - javascript

I have a function, that connects to the API and returns the data:
import {API_KEY, API_URL} from "./constants";
// /**
// * Fetch all tasks
// * #param {function} successCallback - Function that saves incoming data
// */
export const getOperations = async (id, successCallback) => {
try {
const response = await fetch(`${API_URL}/tasks/${id}/operations`, {
headers: {
Authorization: API_KEY,
},
});
const data = await response.json();
if (data.error) {
throw new Error('Error!');
}
successCallback(data.data);
} catch (err) {
console.log(err);
}
};
Then, in one of my react component i call that function to get a data from the specified API:
The props is a required ID.
const [operations, setOperations] = useState([])
console.log(props)
useEffect(() => {
try {
getOperations(data => (props, setOperations(data)))
} catch(e) {
console.log(e)
}
}, [])
The problem is, that my API looks like:
`...api/tasks/function%20(data)%20%7B%20%20%20%20%20%20%20%20return%20props,%20setOperations(data);%20%20%20%`20%20%20%7D/operations`
So i receive 400 error.
Could someone explain me how to get API URL in this situation like:
/api/tasks/{id}/operations
Thanks in advance.

Rather than passing the callback to the result of the function, you could just return the data.
export const getOperations = async (id) => {
try {
const response = await fetch(`${API_URL}/tasks/${id}/operations`, {
headers: {
Authorization: API_KEY,
},
});
const data = await response.json();
if (data.error) {
throw new Error('Error!');
}
return data.data;
} catch (err) {
console.log(err);
}
};
useEffect(() => {
async function apiCall() {
try {
const data = await getOperations(props.id);
setOperations(data)
} catch(err) {
console.log(err)
}
}
apiCall();
}, [props.id])

Related

Async function inside of the React Component returns 'PromiseĀ {<pending>}' no matter what I do

So, I'm trying to run a asynchronous function inside of the functional component in React (NextJS). But no matter what I do, the function just returns a pending promise like this: PromiseĀ {<pending>}. I tried fetching the data from a dummy API, and it works as its supposed to.
The thing is that for this particular case, I need to grab the access_token from the getServerSideProps, which is probably the reason why I am facing these problems (I might be wrong though).
It's worth noting that using a console.log inside of the function, instead of the standard return, gives the correct result.
const checkLoved = async (id: string) => {
try {
const response = await fetch(`https://api.spotify.com/v1/me/tracks/contains/?ids=${id}`, {
headers: {
Authorization: `Bearer ${test.access_token}`,
},
});
const data = await response.json();
return data[0];
} catch (error) {
console.error(error);
}
};
export async function getServerSideProps(context) {
const session = await getSession(context);
if (!session) {
return {
redirect: {
destination: '/login',
permanent: false,
},
};
}
const {
token: { accessToken },
} = session;
const test = await getAccessToken(accessToken);
return {
props: { test, accessToken },
};
}
Additonal info
What I'm trying to achieve:
const Discover: NextPageWithLayout = ({ test }: IDiscover) => {
const checkLoved = async (id: string) => {
try {
const response = await fetch(`https://api.spotify.com/v1/me/tracks/contains/?ids=${id}`, {
headers: {
Authorization: `Bearer ${test.access_token}`,
},
});
const data = await response.json();
return data[0];
} catch (error) {
console.error(error);
}
};
const array = [{ test: 1 }, { test: 2 }];
return (
<div>
{array.map((item) => {
console.log();
return <Component test={checkLoved('7jCy1opEtV4a0TnKrtsSdo')}>{item.test}</Component>;
})}
</div>
);
};
Fixed it by creating a custom hook.
const useLoved = (id, access_token) => {
const [loved, setLoved] = useState(null);
useEffect(() => {
const isLoved = async () => {
const response = await fetch(`https://api.spotify.com/v1/me/tracks/contains/?ids=${id}`, {
headers: {
Authorization: `Bearer ${access_token}`,
},
});
const data = await response.json();
setLoved(data[0]);
};
isLoved();
});
return loved;
};
Then you just need to call it:
const loved = useLoved('7jCy1opEtV4a0TnKrtsSdo', test.access_token);

trying to use the response.json in a second function to filter a specific result

import fetch from "node-fetch";
const URL_API = `https://jsonmock.hackerrank.com/api/countries?`;
async function getResponse() {
let response = await fetch(URL_API, {
method: "GET",
headers: {
"Content-type": "application/json",
},
})
.then((response) => {
return response.json();
})
.then((data) => {
console.log(data);
})
.catch((error) => {
// handle error
console.error(`The unknown error has occurred: ${error}`);
});
}
getResponse();
async function getCapitalCity(country) {
const data = await response.json(); //error mentioned here
for (let info in data) {
console.log(info);
if (info.name === country) {
return info.capital;
} else {
return -1;
}
}
}
console.log(getCapitalCity("Afghanistan"));
working on retrieving a json object. I am trying to use the response object from getResponse() in getCapitalCity() based on country entered (string). My problem is knowing how to use the response in the second function. currently get a promise rejected reference error: response is not defined. thank you in advance.
I have reorganized Your code and added different loops.
const URL_API = `https://jsonmock.hackerrank.com/api/countries?`;
async function getResponse() {
let response = await fetch(URL_API, {
method: 'GET',
headers: {
'Content-type': 'application/json'
}
})
try {
return await response.json();
} catch (error) {
// handle error
console.error(`The unknown error has occurred: ${error}`);
}
}
getResponse();
async function getCapitalCity(country) {
const dat = await getResponse();
const capital = dat.data.filter((item) => item.name === country).map(item => item.capital);
return capital;
}
getCapitalCity('Afghanistan').then(items => console.log('capital: ', items))

React js cannot return data from function

I have two functions, one is a page that calls for data from a function that gets data to and from a server.
The function that gets data to and from a server:
import React, { useEffect, useState, createRef, lazy, useContext } from "react";
import { UserContext } from "./UserContext";
import jwt_decode from "jwt-decode";
import axios from "axios";
export async function getProtectedAsset(url, user, setUser) {
try {
const res = await axios
.post(url, token)
.then((res) => {
console.log(res.data);
return res.data;
})
.catch((err) => {
console.error(err);
});
} catch (error) {
console.log(error);
throw err;
}
}
The code that calls this function:
useEffect(async () => {
try {
let res = await getProtectedAsset(
"http://127.0.0.1:5002/mypage",
user,
setUser
);
console.log(res);
} catch (error) {
console.error(error.message);
}
}, []);
getProtectedAsset will do a successful console.log(res.data); with the data from the server. The calling function that uses useEffect when doing console.log(res); will write undefined to the console.
Why can't I simply return from the function? Obviously the data is received from the server, but for some reason a function cannot return it? I am very confused
Thank you for your help!
You should not use async in useEffect. This is not supported.
I am not sure why you can't use getProtectedAsse(...).then(res=> {}).
But if you want to run getProtectedAsse() synchronously, try like the following instead.
useEffect(() => {
const asyncInternalFunc = async () => {
try {
let res = await getProtectedAsset(
"http://127.0.0.1:5002/mypage",
user,
setUser
);
console.log(res);
return res;
} catch (error) {
console.error(error.message);
}
}
asyncInternalFunc().then();
}, []);
Updated async function to return the response.
export async function getProtectedAsset(url, user, setUser) {
try {
const res = await axios.post(url, token);
return res;
} catch (error) {
console.log(error);
throw err;
}
}

Returning data from getStaticProps

I'm trying to create a function that fetches data from The Guardian API but seem to be getting an error. The response returns this information:
And here is the code for the asynchronous function:
export async function getStaticProps() {
try {
const res = await fetch(
"https://content.guardianapis.com/search?api-key=xxxxxxxx&show-fields=thumbnail"
);
const { results } = await res.json();
const newsList = results.map((news) => {
return { ...news };
});
return {
props: { newsList },
};
} catch (err) {
console.error(err);
}
}
You almost got it. Only 1 thing you are missing is to return props even in the catch block
export async function getStaticProps() {
try {
const res = await fetch(
"https://content.guardianapis.com/search?api-key=xxxxxxxx&show-fields=thumbnail"
);
const { results } = await res.json();
const newsList = results.map((news) => {
return { ...news };
});
return {
props: { newsList },
};
} catch (err) {
console.error(err);
return {
notFound: true /// for rendering 404 page
};
}
}

React: Why am I getting callback is not a function

I am trying to use a callback function in my async code but I am getting the error "callback is not a function". What am I doing wrong? I created the callBack function separately and passed it to the async function as a parameter then called it my react component
function myCallBack() {
setTopicLoaded(true);
}
//async function
export function fetchGroupTopic(groupAdminId, myCallback) {
return async (dispatch) => {
dispatch(getTopic());
try {
const myTopic = [];
if (groupAdminId) {
const response = firestore
.collection("topic")
.where("adminId", "==", groupAdminId);
const data = await response.get();
data.docs.forEach((item) => {
let id = item.id;
let data = item.data();
myTopic.push({ id, ...data });
});
myCallback();
dispatch(setGroupTopic(myTopic));
}
} catch (error) {
console.log(error);
dispatch(getTopicFailure());
}
};
}
// calling it here
React.useEffect(() => {
if (myGroup.length) {
fetchGroupTopic(myGroup[0].adminId,myCallBack);
}
}, [id, submitted, myGroup]);

Categories