I'm building a marketplace where a user get to add his own product to it. I have a form component where the user input details about his product. I have a category and subcategory fields. Once the user chooses a category, the subcategory form gets updated ( by making an api call with the new category) with the list of subcategories related to that category. The problem is the api call is made with the oldest category instead of the the new one.
HERE'S MY CODE
// let's say the initial category is man
const [category, setCategory] = useState("men");
const changeSelectedCategory = (category) => {
// let's say the user get to choose women category from the picker component listed
below
setCategory(category);
// the new category is women
};
useEffect(() => {
// making the api call
getSubCategoriesApi.request({ category: category });
// logging the api fetched data. i'm sending back the selected category by the user
// the problem is here. it keeps logging 'men', yet the new category is women
console.log(getSubCategoriesApi.data());
console.log(category);
// this logs correctly the new category, which is women. the state has been
successfully updated, yet in my api call it wasn't.
}, [category]);
<Picker
items={categories}
changeSelectedCategory={changeSelectedCategory}
placeholder="Categorie"
/>
my express code. note that i'm just sending back the category choosen by the user to see if it did get updated correctly.
router.post("/products/getSubCategories", async (req, res) => {
try {
res.send(req.body);
// sends old category, men. Yet the user did choose women and
state was updated
} catch (err) {
res.status(400).send(err);
}
});
CodePudding user response:
It doesn't look like changeSelectedCategory is being called unless you are calling it inside the Picker Component which can not be seen.
You should use a promise when waiting for data.
getSubCategoriesApi.request({ category: category })
.then(response => {
console.log(getSubCategoriesApi.data());
}).catch(error => {
console.error(error);
});
CodePudding user response:
i Somehow made it work by using axios as api client instead of previously used apisauce.
my api sauce hook
import { useState } from "react";
export default useApi = (apiFunc) => {
const [data, setData] = useState([]);
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
const request = async (...args) => {
setLoading(true);
const response = await apiFunc(...args);
setLoading(false);
if (!response.ok) return setError(true);
setError(false);
setData(response.data);
};
return { data, error, loading, request };
};
My api call
import { create } from "apisauce";
const apiClient = create({
baseURL: "http://192.168.1.42:5000/",
});
const endpoint = "/products";
const getSubCategories = (category) =>
client.post(`${endpoint}/getSubCategories`, category);
export default {
getSubCategories,
};
```
Form component ( previous one that didn't work )
```
const getProductsCategoriesApi = useApi(listingsApi.getCategories)
const [category, setCategory] = useState("men");
const changeSelectedCategory = (category) => {
// let's say the user get to choose women category from the picker component listed
below
setCategory(category);
// the new category is women
};
const getProductsSubCategoriesApi = useApi(listingsApi.getSubCategories);
useEffect(() => {
// making the api call
getSubCategoriesApi.request({ category: category });
// logging the api fetched data. i'm sending back the selected category by the user
// the problem is here. it keeps logging 'men', yet the new category is women
console.log(getSubCategoriesApi.data());
console.log(category);
// this logs correctly the new category, which is women. the state has been
successfully
}, [categorySelected]);
the new api call that did work using axios and ditching api hook i created
useEffect(() => {
axios
.post("http://localhost:5000/products/test", { name: categorySelected })
.then(function (response) {
// successfully logs the new category.
console.log(response.data);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
}, [categorySelected]);