ActiveRecord::RecordInvalid Exception: Validation failed: "Something" must exist - javascript

I am adding all is needed to create a post, but am getting an error message saying "Facility must exist."
For some reason, the facility_id is capturing the name of the facility and not the ID.
I am setting state for facilities, and mapping / filtering for my dropdown. Please see below:
function AddPostForm({ posts, handlePost})
{
const [facilities, setFacilities] = useState ([])
const [procedures, setProcedures] = useState ([])
const uniques = procedures.map(procedure => procedure.procedure)
.filter((value, index, self) => self.indexOf(value) === index )
// console.log("unique procedures:", uniques)
const uniqFacility = facilities.map(facility => facility.name).filter((value,index, self) => self.indexOf(value) === index)
useEffect(() => {
fetch(`/posts/${procedures}`)
.then((r) => r.json())
.then(setProcedures);
}, []);
useEffect(() => {
fetch("/facilities")
.then((r) => r.json())
.then(setFacilities);
}, []);
const [formData, setFormData] = useState({
facility_id: "",
procedure:'',
date_of_procedure:'',
date_of_invoice:'',
patient_cost: "",
insurance_cost: "",
comments: ""
})
const { id } = useParams();
function handleChange(event) {
setFormData({
...formData,[event.target.name]: event.target.value,
});
}
function handleSubmit(event) {
event.preventDefault();
handlePost(formData)
return (
<div >
<form onSubmit={handleSubmit}>
<label htmlFor="facility_id">Facility:</label>
<select
id="facility_id"
name="facility_id"
value={formData.facility_id}
onChange={handleChange} >
<option value="">Select Facility</option>
{uniqFacility.map((facility) => (
<option key={facility.id} value={facility.name}>
{facility}
</option>
))}
</select>
</form>
</div>
);
}
export default AddPostForm;
When I check params in the byebug I see facility_id=>"Name of Facility", and get an error message saying that Facility must exist. I tried adjusting the map / filter function to ...facility => facility.id).filter ... , which ends up giving me the facility_id and creates the post as if the name of the entity was its id.
I think I need to adjust the map/filter formula, but I do not know how. Appreciate if someone help me out here.

Related

Prevent local storage from being changed when filtering in React

Whenever I dispatch a search action using context and useReducer for an object in an array stored in local storage, it returns the object, but when I delete the search query from the input box, the list is not returned and the page is blank, can anyone help please?
This is my context:
const NotesContext = createContext(null);
const NotesDispatchContext = createContext(null);
const getStoredNotes = (initialNotes = InitialNotes) => {
return JSON.parse(localStorage.getItem("storedNotes")) || initialNotes;
};
export const NotesProvider = ({ children }) => {
const [NOTES, dispatch] = useReducer(NotesReducer, getStoredNotes());
useEffect(() => {
localStorage.setItem("storedNotes", JSON.stringify(NOTES));
}, [NOTES]);
return (
<NotesContext.Provider value={NOTES}>
<NotesDispatchContext.Provider value={dispatch}>
{children}
</NotesDispatchContext.Provider>
</NotesContext.Provider>
);
};
export const useNotesContext = () => {
return useContext(NotesContext);
};
export const useNotesDispatchContext = () => {
return useContext(NotesDispatchContext);
};
const App = () => {
const [query, setQuery] = useState("");
const dispatch = useNotesDispatchContext();
useEffect(() => {
if (query.length !== 0) {
dispatch({
type: "searchNotes",
query: query,
});
}
}, [query]);
return (
<div className="container">
<header>
<Title title={"Notes"} className={"app_title"} />
<form className="search_container">
<span class="material-symbols-outlined">search</span>
<input
type="search"
placeholder="search notes"
value={query}
onChange={(e) => setQuery(e.target.value)}
/>
</form>
</header>
This is my reducer function
case "searchNotes": {
[...NOTES].filter((note) =>
note.title.toLowerCase().includes(action.query)
);
}
The function seems to actually remove the all data from the local storage instead of filtering based on the query string.
Issue
When you dispatch searchNotes you are changing NOTES and the blow useEffect runs. So if the filter resulted to an empty array, there would be nothing in localStorage.
useEffect(() => {
localStorage.setItem("storedNotes", JSON.stringify(NOTES));
}, [NOTES]);
Solution
What you can do is to remove that useEffect in App that has query as dependency and dispatching searchNotes. And filter directly while rendering, something like this:
{
NOTES.filter((note) => note.title.toLowerCase().includes(query)).map((note, index) => (
<div key={index}>{note.title}</div>
))
}
And at this point you can remove searchNotes case from your reducer.

React doesn't display initial state of UI on start

I'm building an E-commerce app with React and I stumbled on a problem that React doesn't render the UI based on the initial state when first start the page.
Problem description:
I have a sort state which has the initial state of "latest", based on this Sorting functionality - if sort has a value of "latest" - it will sort and return the newest items first.
But on start or when I refresh the page, the default value and state of sort will still be "latest" but the UI just display the oldest items first.
I have to click on other option and then choose the Latest option again for the sort logic to go through. When I refresh the page, the problem is back.
The logic for sorting other values works fine. In the demo below, you can see I log out the sort current state. On start, the sort value is already "latest".
In the API product.js file, I already sorted the items with mongoose by the field createdAt - 1 but seems like it doesn't apply on the UI?
-> What would be the case here that makes React not render the items based on initial state and how can we fix it?
Below is my code:
ProductList.jsx
const ProductList = () => {
const location = useLocation()
const category = location.pathname.split("/")[2]
const [filters, setFilters] = useState({});
const [sort, setSort] = useState("latest");
// For Filters Bar
const handleFilters = (e) => {
const value = e.target.value
// When choosing default value, show all products:
if (value === "") {
return setFilters([])
} else {
setFilters({
...filters,
[e.target.name]: value,
})
}
}
return (
<Container>
<Navbar />
<Announcement />
<Title>Dresses</Title>
<FilterContainer>
<Filter>
<FilterText>Filter Products: </FilterText>
<Select name="color" onChange={handleFilters}>
<Option value="">All Color</Option>
<Option value="white">White</Option>
<Option value="black">Black</Option>
<Option value="brown">Brown</Option>
<Option value="red">Red</Option>
<Option value="blue">Blue</Option>
<Option value="yellow">Yellow</Option>
<Option value="green">Green</Option>
</Select>
<Select name="size" onChange={handleFilters}>
<Option value="">All Size</Option>
<Option>XS</Option>
<Option>S</Option>
<Option>M</Option>
<Option>L</Option>
<Option>XL</Option>
<Option>36</Option>
<Option>37</Option>
<Option>38</Option>
<Option>39</Option>
<Option>40</Option>
<Option>41</Option>
<Option>42</Option>
<Option>43</Option>
</Select>
</Filter>
<Filter>
<FilterText>Sort Products: </FilterText>
<Select onChange={e => setSort(e.target.value)}>
<Option value="latest">Latest</Option>
<Option value="oldest">Oldest</Option>
<Option value="asc">Price ↑ (Low to High)</Option>
<Option value="desc">Price ↓ (High to Low)</Option>
</Select>
</Filter>
</FilterContainer>
<Products category={category} filters={filters} sort={sort} />
<Newsletter />
<Footer />
</Container>
);
}
Products.jsx
const Products = ({ category, filters, sort }) => {
const [products, setProducts] = useState([])
const [filteredProducts, setFilteredProducts] = useState([])
useEffect(() => {
const getProducts = async () => {
try {
const res = await axios.get( category
? `http://localhost:5000/api/products?category=${category}`
: `http://localhost:5000/api/products`
)
setProducts(res.data)
} catch (err) {
console.log(`Fetch all items failed - ${err}`)
}
}
getProducts()
}, [category])
useEffect(() => {
category && setFilteredProducts(
products.filter(item =>
Object.entries(filters).every(([key, value]) =>
item[key].includes(value)
)
)
)
}, [category, filters, products])
// Sorting:
useEffect(() => {
console.log(sort)
if (sort === "latest") {
setFilteredProducts(prev =>
[...prev].sort((a, b) => b.createdAt.localeCompare(a.createdAt))
)
} else if (sort === "asc") {
setFilteredProducts(prev =>
[...prev].sort((a, b) => a.price - b.price)
)
} else if (sort === "desc") {
setFilteredProducts(prev =>
[...prev].sort((a, b) => b.price - a.price)
)
} else {
setFilteredProducts(prev =>
[...prev].sort((a, b) => a.createdAt.localeCompare(b.createdAt))
)
}
}, [sort])
return (
<Container>
<Title>Popular In Store</Title>
<ProductsWrapper>
{filteredProducts.map(item => (
<Product key={item._id} item={item} />
))}
</ProductsWrapper>
</Container>
);
}
API Route - product.js
const router = require('express').Router()
const { verifyTokenAndAdmin } = require('./verifyToken')
const Product = require('../models/Product')
// .... (Other CRUD)
// GET ALL PRODUCTS
router.get("/", async(req, res) => {
const queryNew = req.query.new
const queryCategory = req.query.category
try {
let products = []
if(queryNew) {
products = await Product.find().sort({ createdAt: -1 }).limit(5)
} else if (queryCategory) {
products = await Product.find({
categories: {
$in: [queryCategory],
},
})
} else {
products = await Product.find()
}
res.status(200).json(products)
} catch(err) {
res.status(500).json(`Cannot fetch all products - ${err}`)
}
})
module.exports = router
Demo:
Explain demo: On start, it renders oldest items first. Have to choose another option and then return to the latest option for it to render. But in the console, the initial state of sort is already "latest" but it doesn't match with the useEffect sorting logic.
Update
According #idembele70's answer, I mistyped the initial state of filters to Array.
I have fixed it and also added a name="sort" on the Sort select.
I also replaced value="latest" with defaultValue="latest" for my Sort select bar. -> This makes the Latest option stop working so I don't think it can be used in this case?
The result is still the same, the UI doesn't render the logic of the Sort bar to display the latest items first.
Code
const ProductList = () => {
const location = useLocation()
const category = location.pathname.split("/")[2]
const [filters, setFilters] = useState({});
const [sort, setSort] = useState("latest");
const handleFilters = (e) => {
const value = e.target.value
// When choosing default value, show all products:
if (value === "") {
setFilters({}) // Changed from array to object
} else {
setFilters({
...filters,
[e.target.name]: value,
})
}
}
...
<Filter>
<FilterText>Sort Products: </FilterText>
<Select name="sort" onChange={e => setSort(e.target.value)} >
<Option defaultValue="latest">Latest</Option>
<Option value="oldest">Oldest</Option>
<Option value="asc">Price ↑ (Low to High)</Option>
<Option value="desc">Price ↓ (High to Low)</Option>
</Select>
</Filter>
You shouldn't put the changed products to the state, as it makes it extra complex to keep it updated and you need to deal with various useEffect cases. Instead it's better to define sorting and filtering functions and apply them at the render time. This way you'll ensure the render result is always up-to-date with the data:
const filterProducts = (products) => {
if (!category) {
return products;
}
return products.filter(item =>
Object.entries(filters).every(([key, value]) =>
item[key].includes(value),
),
);
};
const sortProducts = (products) => {
switch (sort) {
case "asc":
return [...products].sort((a, b) => a.price - b.price);
case "desc":
return [...products].sort((a, b) => b.price - a.price);
case "latest":
default:
return [...products].sort((a, b) => a.createdAt.localeCompare(b.createdAt));
}
};
return (
<Container>
<Title>Popular In Store</Title>
<ProductsWrapper>
{sortProducts(filterProducts(products)).map(item => (
<Product key={item._id} item={item} />
))}
</ProductsWrapper>
</Container>
);
If you put log inside your useEffect hooks, I would assume the execution order is:
[sort]->[category]->[category, filters, products]
The useEffect of [category] has an ajax call and it will definitely take effect after [sort], when it taking effect, it will run your query which is not using req.query.new, so it will just run this branch(i guess you do have category)
else if (queryCategory) {
products = await Product.find({
categories: {
$in: [queryCategory],
},
})
}
, it should default return a ascending list just match 'oldest' option.
So in general, your sort effect is not working at all on initial load because it will always get overwritten by other effects.
So either you make all the query with default descending condition to match the default 'latest' option, or you could trigger sort after any query was performed, option 2 looks better but you need to consider what's your expected behavior of sort when changing other elements(filter, category).
i faced a problem with this code from lama, so first i see a error from you define useState with a initialState as object and in your handleFilters you use an array
const [filters, setFilters] = useState({}); // you use Object there
const handleFilters = (e) => {
const value = e.target.value
products:
if (value === "") {
return setFilters([]) //. you should use object there not array.
} else {
setFilters({
...filters,
[e.target.name]: value,
})
}}
So in React when you use onChange it's recommended to use a value or defaultValue in your html elems
to solve this problem take a look to this CodeSandebox link: https://codesandbox.io/s/determined-hopper-gp9ym9?file=/src/App.js
Let me know if it has solved your problem.

React : Empty values on PUT for axios

I have a simple list that I get from an API using axios.
Every element is a modifiable input, with it own update button.
After changing the data of an input, and while performing PUT request, console.log(test); returns empty values.
I checked console.log(newList); which is the array of the list, and the changing data are indeed happening in the list, but it seems they can't be sent to the server.
Note : The API is just for testing, the PUT method may not work, but atleast the values in the console should be sent.
Note2 : I don't know how to place the id of an item of the list in the url so you may encounter an error. / You can try with 1,2 or 3 instead for testing.
https://codesandbox.io/s/quizzical-snowflake-dw1xr?file=/src/App.js:1809-1834
import React, { useState, useEffect } from "react";
import axios from "axios";
export default () => {
const [list, setList] = React.useState([]);
const [name, setName] = React.useState("");
const [description, setDescription] = React.useState("");
const [city, setCity] = React.useState("");
// Getting initial list from API
useEffect(() => {
axios
.get("https://6092374385ff5100172122c8.mockapi.io/api/test/users")
.then((response) => {
setList(response.data);
console.log(response);
})
.catch((err) => console.log(err));
}, []);
// onUpdate to update the data in the API
const onUpdate = (e) => {
e.preventDefault();
const test = {
name: name,
description: description,
city: city
};
console.log(test);
// axios request PUT data on API
axios
.put(
"https://6092374385ff5100172122c8.mockapi.io/api/test/users" + id,
test
)
.then((res) => {
alert("success");
console.log(res);
})
.catch((error) => {
console.log(error);
});
// axios request GET to get the new modified list from the database, after the update
axios
.get("https://6092374385ff5100172122c8.mockapi.io/api/test/users")
.then((res) => {
alert("success");
console.log(res);
})
.catch((error) => {
console.log(error);
});
};
// Handler for changing values of each input
function handleChangeUpdate(id, event) {
const { name, value } = event.target;
const newList = list.map((item) => {
if (item.id === id) {
const updatedItem = {
...item,
[name]: value
};
return updatedItem;
}
return item;
});
setList(newList);
console.log(newList);
}
return (
<div>
<ul>
<div>
{list.map((item) => (
<li key={item.id}>
<input
className="form-control"
name="name"
onChange={(event) => handleChangeUpdate(item.id, event)}
defaultValue={item.name}
></input>
<input
className="form-control"
name="description"
onChange={(event) => handleChangeUpdate(item.id, event)}
defaultValue={item.description}
></input>
<input
className="form-control"
name="city"
onChange={(event) => handleChangeUpdate(item.id, event)}
defaultValue={item.city}
></input>
<button onClick={onUpdate}>Update</button>
</li>
))}
</div>
</ul>
</div>
);
};
It's because you never set the values of the props. That is why they never change from their initial values. You just update the list prop in handleChangeUpdate. There are two steps you need to take with the existing file structure:
Make handleChangeUpdate be able to differentiate between different props (city, description, etc.). For example, by passing the prop's name.
Update the prop's value in the handleChangeUpdate.
To realize the first step, you can change the input tag like the following:
{/* attention to the first argument of handleChangeUpdate */}
<input
className="form-control"
name="name"
onChange={(event) => handleChangeUpdate("name", item.id, event)}
defaultValue={item.name}
></input>
Then, you need to adjust the handleChangeUpdate:
if (name === "name") {
setName(value);
} else if (name === "description") {
setDescription(value);
} else if (name === "city") {
setCity(value);
}
By the way, list is not a good name for a variable.
Alternatively
Without creating new parameters, you can also use only the event to set the props
// Handler for changing values of each input
function handleChangeUpdate(id, event) {
const { name, value } = event.target;
const newList = list.map((item) => {
if (item.id === id) {
const updatedItem = {
...item,
[name]: value
};
return updatedItem;
}
return item;
});
setList(newList);
console.log(newList);
if (name === "name") {
setName(value);
} else if (name === "description") {
setDescription(value);
} else if (name === "city") {
setCity(value);
}
}
I think you have 3 errors in the onUpdate function.
You are not passing the id of the item from the onClick event
Your put method should be change
You should not perform get request as soon as after the put request, because sometimes the backend will not updated yet.
You can update your code as below,
1.Pass the id of the item when the button is clicked.
<button onClick={onUpdate(item.id)}>Update</button>
Modify the put method, passing the id
axios
.put(
`https://6092374385ff5100172122c8.mockapi.io/api/test/users/${e}`,
test
).then((res) => {
alert("success");
console.log(res);
})
.catch((error) => {
console.log(error);
});
3.Perform the get request after the response of the put request
const onUpdate = (e) => {
const test = {
name: name,
description: description,
city: city
};
console.log(test);
// axios request PUT data on API
axios
.put(
`https://6092374385ff5100172122c8.mockapi.io/api/test/users/${e}`,
test
)
.then((res) => {
console.log(res);
// axios request GET to get the new modified list from the database, after the update
axios
.get("https://6092374385ff5100172122c8.mockapi.io/api/test/users")
.then((res) => {
alert("success");
console.log(res);
})
.catch((error) => {
console.log(error);
});
})
.catch((error) => {
console.log(error);
});
};

Reactjs variable is returning with undefined after useEffect

I am very new to Reactjs, I am working on retrieving some data in order to display it, everything gets displayed however, when I filter there is an error that comes up "Cannot read property 'filter' of undefined", after debugging I found out that dataList is returning with undefined when typing anything in the search bar.
Appreciate your assistance.
function App() {
var dataList;
useEffect(() => {
// http get request
const headers = {
'Content-Type': 'application/json',
'Authorization': '***********************',
'UserAddressId': ****,
'StoreId': *
}
axios.get('https://app.markitworld.com/api/v2/user/products', {
headers: headers
})
.then((response) => {
dataList = response.data.data.products
setData(dataList)
})
.catch((error) => {
console.log(error)
})
}, []);
const [searchText, setSearchText] = useState([]);
const [data, setData] = useState(dataList);
// exclude column list from filter
const excludeColumns = ["id"];
// handle change event of search input
const handleChange = value => {
setSearchText(value);
filterData(value);
};
// filter records by search text
const filterData = (value) => {
console.log("dataList", dataList)
const lowercasedValue = value.toLowerCase().trim();
if (lowercasedValue === "") setData(dataList);
else {
const filteredData = dataList.filter(item => {
return Object.keys(item).some(key =>
excludeColumns.includes(key) ? false :
item[key].toString().toLowerCase().includes(lowercasedValue)
);
});
setData(filteredData);
}
}
return (
<div className="App">
Search: <input
style={{ marginLeft: 5 }}
type="text"
placeholder="Type to search..."
value={searchText}
onChange={e => handleChange(e.target.value)}
/>
<div className="box-container">
{data && data.length > 0 ? data.map((d, i) => {
return <div key={i} className="box">
<b>Title: </b>{d.title}<br />
<b>Brand Name: </b>{d.brand_name}<br />
<b>Price: </b>{d.price}<br />
<b>Status: </b>{d.status}<br />
</div>
}) : "Loading..."}
<div className="clearboth"></div>
{data && data.length === 0 && <span>No records found to display!</span>}
</div>
</div>
);
}
export default App;
You're mixing up a stateful data variable with a separate non-stateful, local dataList variable. The dataList only gets assigned to inside the axios.get, so it's not defined on subsequent renders; the setData(dataList) puts it into the stateful data, but the dataList on subsequent renders remains undefined.
To make things easier to understand, remove the dataList variable entirely, and just use the stateful data.
You also probably don't want to discard the existing data when the user types something in - instead, figure out what items should be displayed while rendering; rework the filterData so that its logic is only carried out while returning the JSX.
const [searchText, setSearchText] = useState([]);
const [data, setData] = useState([]);
useEffect(() => {
// http get request
const headers = {
'Content-Type': 'application/json',
'Authorization': '***********************',
'UserAddressId': ****,
'StoreId': *
}
axios.get('https://app.markitworld.com/api/v2/user/products', {
headers: headers
})
.then((response) => {
setData(response.data.data.products);
})
.catch((error) => {
console.log(error)
})
}, []);
// handle change event of search input
const handleChange = value => {
setSearchText(value);
};
// filter records by search text
const filterData = () => {
const lowercasedValue = searchText.toLowerCase().trim();
return lowercasedValue === ""
? data
: data.filter(
item => Object.keys(item).some(
key => excludeColumns.includes(key) ? false :
item[key].toString().toLowerCase().includes(lowercasedValue)
)
);
}
And change
{data && data.length > 0 ? data.map((d, i) => {
to
{filterData().map((d, i) => {
Your searchText should also be text, not an array: this
const [searchText, setSearchText] = useState([]);
should be
const [searchText, setSearchText] = useState('');
First of all, you don't need to maintain an additional non-state variable dataList as the local state data would serve the purpose.
API Call Code:
You should directly store the response from API after null checks satisfy.
useEffect(() => {
const headers = {
// key value pairs go here
};
// http request
axios.get(endPoint, {
headers,
})
.then((response) => {
// set data directly null checks
setData(response.data.data.products);
})
.catch((error) => {
console.log(error);
});
}, []);
Filteration Code
Use useCallback hook which would return a memoized version of the callback, unless the value of data changes.
const filterData = useCallback((value) => {
console.log('data', data);
// rest of code
}, [data]);

Chaining Fetch Calls React.js

I'm making an application where I have to grab certain data from the Github API. I need to grab the name, url, language and latest tag. Because the latest tag is in a separate url, I need to make another fetch call there to grab that data.
I'm running into a certain amount of errors.
1st being the typeError cannot read property 'name' of undefined. I'm sure this is from the fetch call to the tag url where there isn't any data. I'm not really sure how to check if it's undefined. I've tried calling checking to see if the typeof data is undefined and so on but still get the error.
2nd problem being my tag url data doesn't show up with the other data. I'm sure I'm chaining the data wrong because when I click the add button it shows up.
Here is my code:
import React, { Component } from 'react'
import './App.css'
class App extends Component {
state = {
searchTerm: '',
repos: [],
favourites: []
}
handleChange = e => {
const { searchTerm } = this.state
this.setState({ searchTerm: e.target.value })
if (searchTerm.split('').length - 1 === 0) {
this.setState({ repos: [] })
}
}
findRepos = () => {
const { searchTerm } = this.state
// First api call here
fetch(`https://api.github.com/search/repositories?q=${searchTerm}&per_page=10&access_token=${process.env.REACT_APP_TOKEN}
`)
.then(res => res.json())
.then(data => {
const repos = data.items.map(item => {
const { id, full_name, html_url, language } = item
const obj = {
id,
full_name,
html_url,
language,
isFavourite: false
}
// Second api call here. I need the data from map to get the tags for the correct repo
fetch(`https://api.github.com/repos/${full_name}/tags`)
.then(res => res.json())
.then(data => {
obj.latest_tag = data[0].name
})
.catch(err => console.log(err))
return obj
})
this.setState({ repos })
})
.catch(err => console.log(err))
}
render() {
const { searchTerm, repos, favourites } = this.state
return (
<div className="App">
<h1>My Github Favorites</h1>
<input
type="text"
placeholder="search for a repo..."
value={searchTerm}
onChange={e => this.handleChange(e)}
onKeyPress={e => e.key === 'Enter' && this.findRepos()}
/>
<button
type="submit"
onClick={this.findRepos}>
Search
</button>
<div className="category-container">
<div className="labels">
<h5>Name</h5>
<h5>Language</h5>
<h5>Latest Tag</h5>
</div>
// Here I list the data
{repos.map(repo => (
<div key={repo.id}>
<a href={repo.html_url}>{repo.full_name}</a>
<p>{repo.language}</p>
{repo.latest_tag ? <p>{repo.latest_tag}</p> : <p>-</p>}
<button onClick={() => this.addToFavs(repo)}>Add</button>
</div>
))}
<h1>Favourites</h1>
{favourites.map(repo => (
<div key={repo.id}>
<a href={repo.html_url}>{repo.full_name}</a>
<p>{repo.language}</p>
<p>{repo.latest_tag}</p>
<button>Remove</button>
</div>
))}
</div>
</div>
)
}
}
export default App
If you use Promise.all(), you could rewrite your code like the following.
findRepos = () => {
const { searchTerm } = this.state;
// First api call here
const first = fetch(
`https://api.github.com/search/repositories?q=${searchTerm}&per_page=10&access_token=${
process.env.REACT_APP_TOKEN
}`
);
// Second api call here. I need the data from map to get the tags for the correct repo
const second = fetch(`https://api.github.com/repos/${full_name}/tags`);
Promise.all([first, second])
.then((res) => Promise.all(res.map(r => r.json())))
.then([data1, data2] => {
data1.then((firstData) => {
/*Do something you want for first.*/
});
data2.then((secondData) => {
/*Do something you want for second.*/
});
})
.catch((err) => console.log(err));
};
Hope this works for you.

Categories