I make a request to 'https://pokeapi.co/api/v2/pokemon/${name}' to obtain the information of a specific pokemon, the problem is that the name must be the same otherwise it returns undefined, I need to filter many pokemons, for example: if I search for char it should return charmeleon and charizard, because they both have 'char'. How can I filter a lot of pokemons?
const params = {
headers: {
'Content-Type': 'application/json'
}
}
const searchPokemon = async name => {
const url = `https://pokeapi.co/api/v2/pokemon/${name}`
try {
const response = await fetch(url, params);
const result = await response.json();
return result;
} catch (error) {
console.log(error)
}
}
To get a list of all possible pokemon names, you can make a request to https://pokeapi.co/api/v2/pokemon?limit=100000 (where 100000 is larger than the number of pokemon that exist. There appear to be only 1118 pokemon as of now.)
The result looks like this:
[
{
name:"bulbasaur",
url:"https://pokeapi.co/api/v2/pokemon/1/"
},
{
name:"ivysaur",
url:"https://pokeapi.co/api/v2/pokemon/2/"
},
{
name:"venusaur",
url:"https://pokeapi.co/api/v2/pokemon/3/"
},
...
]
Then you can filter out that list based on the names you are looking for. After you find the name you want, you can use the corresponding URL to get more information.
Related
I am wanting to make my website able to add a name and dog breed to an existing list of animals.
export const addNewPlayer = async (playerObj) => {
try {
const response = await fetch(
`${APIURL}players/`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Rufus',
breed: 'Irish Setter',
}),
}
);
const result = await response.json();
console.log(result);
} catch (err) {
console.error(err);
}
};
This is the function to create the new player
let form = document.querySelector('#new-player-form > form');
form.addEventListener('submit', async (event) => {
event.preventDefault();
let playerData = {
name: form.elements.name.value,
breed: form.elements.breed.value
}
console.log(playerData)
const players = await fetchAllPlayers()
renderAllPlayers(players)
addNewPlayer(playerData);
renderNewPlayerForm()
});
This is the form that I have here too.
I am just stumped on how to change the "Rufus" and "Irish Setter" to user inputs. When logging the playerData, I can see it running when inspecting, but it only adds the spot for "Rufus".
Some of the code was given, and I am only stumped on the playerObj parameter that was first in the code. I do not see a use, and most of the stuff in addNewPlayer is also given in the API website that was a part of the project. I tried to make the name and breed empty strings but got an error from that.
All the information you need is in your playerData variable. So, just add the info from it inside your requisiton body. try this:
export const addNewPlayer = async (playerObj) => {
//...
body: JSON.stringify({
name: playerObj.name,
breed: playerObj.breed,
}),
In SingleBlogPost.jsx i have:
export async function getStaticPaths() {
const res = await fetch("http://localhost:1337/api/posts");
let { data } = await res.json();
const paths = data.map((data) => ({
params: { slug: data.attributes.slug },
}));
return {
paths,
fallback: "blocking",
};
}
where I generate blog pages by their slug.
But then in getStaticProps I need to fetch single post by slug but I want to do it by id.
export async function getStaticProps(context) {
console.log("context", context);
const { slug } = context.params;
console.log("slug is:", slug);
const res = await fetch("http://localhost:1337/api/posts");
const { data } = await res.json();
return {
props: {
data,
},
revalidate: 10, // In seconds
};
}
And I want to keep url like /blog/:slug , I dont want to include id. in url .When I already fetch all posts in getStaticPaths how I can access post id in getStaticProps to avoid fetching by slug?
You can filter your API response by your slug to get the same result
const res = await fetch(`http://localhost:1337/api/posts?filters[slug][$eq]${slug}`);
This will generate your desired result
It looks like recently released a workaround using a file system cache.
The crux of the solution is that they save the body object in memory, using something like this:
this.cache = Object.create(null)
and creating methods to update and fetch data from the cache.
Discussion here: https://github.com/vercel/next.js/discussions/11272#discussioncomment-2257876
Example code:
https://github.com/vercel/examples/blob/main/build-output-api/serverless-functions/.vercel/output/functions/index.func/node_modules/y18n/index.js#L139:10
I found a concise work around that uses the object-hash package. I basically create a hash of the params object and use that to create the tmp filename both on set and get. The tmp file contains a json with the data I want to pass between the two infamous static callbacks.
The gist of it:
function setParamsData({params, data}) {
const hash = objectHash(params)
const tmpFile = `/tmp/${hash}.json`
fs.writeFileSync(tmpFile, JSON.stringify(data))
}
function getParamsData (context) {
const hash = objectHash(context.params)
const tmpFile = `/tmp/${hash}.json`
context.data = JSON.parse(fs.readFileSync(tmpFile))
return context
}
We can then use these helpers in the getStaticPaths and getStaticProps callbacks to pass data between them.
export function getStaticPaths(context) {
setParamsData({...context, data: {some: 'extra data'})
return {
paths: [],
fallback: false,
}
}
export function getStaticProps(context) {
context = getParamsData(context)
context.data // => {some: 'extra data'}
}
I'm sure someone can think of a nicer API then re-assigning a argument variable.
The tmp file creation is likely not OS independent enough and could use some improvement.
I need to visit the pagination URLs to get every list item in them and get all lists in one big array of objects to be able to pre-render in getStaticPaths(). After little thinking I decided to use for(..) loop in. Since the query string just asks for page number in the URL, I decided it would be the right solution.
My code:
export async function getStaticPaths() {
let bookPages = [];
for (let pageNo = 1; pageNo=5; pageNo ++) {
const res = await axiosInstance.get(`/?page=${pageNo}`);
const resultsList = await res.data.results;
bookPages.push(resultsList);
}
const paths = bookPages.map((book) => ({
params: { id: book.id.toString() },
}))
return { paths, fallback: false }
}
There are just 5 pages and no new data will be added. Every result response contains an array that has a list of 30 objects. I want to put all the 30 objects per URL to the one big array called bookPages, totaling 150 objects in the array, and use it to return paths.
When building, Nextjs collects page data for 60 seconds, then runs again as it fails to collect the data and throws this error:
> Build error occurred
Error: Collecting page data for /book/[id] is still timing out after 2 attempts. See more info here https://nextjs.org/docs/messages/page-data-collection-timeout
But if I request for only the first page, it builds properly.
export async function getStaticPaths() {
const res = await axiosInstance.get('/?page=1');
const resultsList = await res.data.results;
const paths = resultsList.map((book) => ({
params: { id: book.id.toString() },
}))
return { paths, fallback: false }
}
Update:
I tried with Promise.all() in this manner but it failed the build:
let bookPages = [];
let links = [];
for (let paginate=1; paginate=5; paginate++) {
links.push(`${process.env.NEXT_PUBLIC_URL}?page=${paginate}/`);
}
let requests = links.map(url => axios.get(url));
Promise.all(requests)
.then(responses => responses.forEach(
response => bookPages.push(response.data.results)
));
const paths = bookPages.map((book) => ({
params: { id: book.id.toString() },
}))
I am trying to retrieve records based on a value in a mongo dataset that is in a nested object.
data is an object and documentId is a field within it and I want to retrieve just the objects within data that have the documentId of "5da713edf0a1645ae95b11oo"
I tried this code
const res = await axios.get('/api/card',{
params:{
data:documentId: "5da713edf0a1645ae95b11oo"
}
});
but it just returns all the records
Try one of these:
const res = await axios.get('/api/card',{
params:{
documentId: "5da713edf0a1645ae95b11oo"
}
});
This would be a GET request to /api/card?documentId=5da713edf0a1645ae95b11oo
or
const res = await axios.get('/api/card',{
params:{
data: {
documentId: "5da713edf0a1645ae95b11oo"
}
}
});
This would be a GET request to something like /api/card?data=%7B%22documentId%22%3A%225da713edf0a1645ae95b11oo%22%7D
...where %7B%22documentId%22%3A%225da713edf0a1645ae95b11oo%22%7D is URL encoded version of {"documentId":"5da713edf0a1645ae95b11oo"}
according to the documentations it says that we can not do what you have done.
axios.get('/api/card')
.then((res) => {
const data = res.data.id;
//handle your response here.
//can write your logic to retrieve your specific data
});
for further in formations refer this doc
I'm going to assume the data you're receiving on the response is an array of objects. You can filter through it. You're going to have to loop through the data though.
const res = await axios.get('/api/card')
const filteredData = res.data.filter((item) => item.documentId === '5da713edf0a1645ae95b11oo')
You can try this:
data_get() {
axios.get('/api/card')
.then((res) => {
this.setState({
documentId: res.data.id, //5da713edf0a1645ae95b11oo
});
});
}
I'm trying to interact with the API of processmaker.
I have made a simple form to authenticate and get the authorization token, which is needed to interact with the rest of the API.
I am able to use the token to output a json response of created projects after login. The response is an array of objects.
I need to get the prj_uid for an api request so I want to extract these, but I've had little luck using map.
How can I iterate over the response and get prj_name and prj_uid for each of the objects in the array?
import React, { useState, useEffect } from "react";
//import ResponsiveEmbed from "react-responsive-embed";
const Tasks = ({ loggedIn }) => {
const [hasError, setErrors] = useState(false);
const [projects, setProjects] = useState([]);
const url = "http://127.0.0.1:8080/api/1.0/workflow/project";
useEffect(() => {
let access_token = sessionStorage.getItem("access_token");
async function fetchData() {
const response = await fetch(url, {
method: "GET",
withCredentials: true,
timeout: 1000,
headers: {
Authorization: "Bearer " + access_token
}
});
response
.json()
.then(response => setProjects(response))
.catch(err => setErrors(err));
}
fetchData();
}, [loggedIn]);
console.log(JSON.stringify(loggedIn) + " logged in, displaying projects");
console.log(projects + " projects");
if (!loggedIn) {
return <h1>Error</h1>;
} else {
return (
<>
<p>Login success!</p>
<h2>Projects:</h2>
<span>{JSON.stringify(projects)}</span>
<div>Has error: {JSON.stringify(hasError)}</div>
</>
);
}
};
export default Tasks;
Stringified Response:
[
{
"prj_uid":"1755373775d5279d1a10f40013775485",
"prj_name":"BPMN Process",
"prj_description":"This is a processmaker BPMN Project",
"prj_category":"8084532045d5161470c0de9018488984",
"prj_type":"bpmn",
"prj_create_date":"2019-08-13 08:50:25",
"prj_update_date":"2019-08-13 09:04:16",
"prj_status":"ACTIVE"
},
{
"prj_uid":"7459038845d529f685d84d5067570882",
"prj_name":"Purchase Request",
"prj_description":"",
"prj_category":"2284311685392d2e70f52e7010691725",
"prj_type":"bpmn",
"prj_create_date":"2019-08-13 11:30:48",
"prj_update_date":"2019-08-13 12:20:05",
"prj_status":"ACTIVE"
}
]
Array.map() is your answer- you had it right.
its as simple as:
let mappedObject = result.map( el => ({ prj_name, prj_uid }) );
el is every element in the array, and we construct the new array with an object containing only prj_name and prj_uid. Because el alraeady has those properties with those names, we do not need to write { prj_name: el.prj_name } when we construct the new object, it is implied and will do the trick with only the property names there.
mappedObject will now hold an array of objects consists only of the asked properties.
You might wanna read more about map to understand it better- Array.map()
If loggedIn is the json object, then you can do this:
const uidNameArr = loggedIn.map((item) => { // returns an array of arrays with the values you want.
return [item.prj_uid, item.prj_name]
})
uidNameArr.forEach(([uid,name]) => {
console.log(`${name} has a uid of ${uid}`)
})