0

I'm working with React.js and I have the following problem:

import axios from "axios";

export default function Home() {

    const [products, setProducts] = useState([]);
    
    const ax = axios.create({ headers: { Accept: 'application/json' }});

    function test() {
        const res = ax.get("https://vtexstore.codeby.com.br/api/catalog_system/pub/products/search").then((response) => {
            // expected the setProducts to be filled with the return of this request
            setProducts(response.data);
        });
    }

    test();
    
    // and when I get here to see if the products have been filled, I get an empty array [ ]

    console.log(products);
    
    /* 
        as the products variable was not filled within the axios promise by setProducts, 
        there is no way to throw the products array here in the HTML to make a forEach or
        a map to look cute together with the tags 
    */
    
    return (
        <sup>how sad, with the product array empty, I can't put the data here '-'</sup>
    );
    
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>

See how the result comes out in the IDE console:

enter image description here

I'm in Visual Studio not knowing what to do, I'm new to ReactJS with NextJS and from an early age I've been trying to see if I could solve this problem, but without success.

What can I do to bring the products to the HTML page?


UPDATE: As per the solution below, I created a possible workaround that indicates a path that could have returned a solution

ax.get("https://vtexstore.codeby.com.br/api/catalog_system/pub/products/search/", {})
.then((response) => setProducts(response.data))
.catch((error) => {
    console.log(error); // AxiosError {message: 'Network Error', name: 'AxiosError', ...}
    console.log(error.status); // undefined
    console.log(error.code); // ERR_NETWORK
});

useEffect(() => {
    console.log(products);
}, []);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.0.2/umd/react-dom.production.min.js"></script>

and I'm getting the same error that I put in the comments of the first answer below:

enter image description here

but when I change the setProducts by the console.log to see if it returns the same result, this appears in the terminal where my next.js application is running

that:

ax.get("https://vtexstore.codeby.com.br/api/catalog_system/pub/products/search/", {})
.then((response) => console.log(response.data.length)) // returns the length of the products array

returns this when I update my app:

enter image description here

NOTE: That's why I'm not able to understand my application in Next.js. I'm following all the correct guidelines, writing the code perfectly using axios and when I run the application on the website it gives a network error and doesn't show exactly the amount of products that were displayed in the terminal where my application is running.

I've already configured all the request headers correctly, enabling CORS to allow external requests with other API's, and I still don't succeed in returning the data to my application's page.

pe.Math
  • 89
  • 1
  • 7

1 Answers1

0

Wrap the stuff you have to fetch products inside useEffect hook

useEffect(()=>{ 
const ax = axios.create({ headers: { Accept: 'application/json' }});


function test() {
    const res = ax.get("https://vtexstore.codeby.com.br/api/catalog_system/pub/products/search").then((response) => {
        // expected the setProducts to be filled with the return of this request
        setProducts(response.data);
console.log(response.data)
    });
}
test();
},[])

Then in your return of the component, you can use map on products array with null and undefined checks Like

{products && products.map(product=>{})}

Shahin Nazer
  • 166
  • 1
  • 6
  • Use effect documentation here : https://reactjs.org/docs/hooks-effect.html – Shahin Nazer Jun 26 '22 at 05:58
  • the solution above seems to work, but when I ran the code above, I received the following return in the browser: `Access to XMLHttpRequest at 'https://vtexstore.codeby.com.br/api/catalog_system/pub/products/search' from origin 'https://3000-mat3ed18-codeby-v5gsjbiwi5e.ws-us47.gitpod.io' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.` – pe.Math Jun 26 '22 at 06:07
  • `GET https://vtexstore.codeby.com.br/api/catalog_system/pub/products/search net::ERR_FAILED 206` – pe.Math Jun 26 '22 at 06:08
  • `Uncaught (in promise) AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …} ` – pe.Math Jun 26 '22 at 06:09
  • This is an error where you are not allowed to make the request to this url because this url does not allow it – Shahin Nazer Jun 26 '22 at 11:42
  • What can I do to resolve this issue? On the documentation page, nothing is said about CORS and oddly enough when I do the same procedure as I did on the official website, the request is successful, only here that this problem occurs. – pe.Math Jun 26 '22 at 18:28
  • https://developers.vtex.com/vtex-rest-api/reference/productsearchfilteredandordered – pe.Math Jun 26 '22 at 18:31
  • I understand, many internal API's block CORS for other devices not to access and so I try to imagine some solution to this problem. – pe.Math Jun 26 '22 at 18:33
  • In the browser I can access this GET request without headers, **so could I save the JSON with all the data and use it in my project?** – pe.Math Jun 26 '22 at 18:35
  • You could also have an api in between which your app will hit and then this app will fetch the data for you. Most apis allow other apis to hit. Only browsers are restricted – Shahin Nazer Jun 27 '22 at 04:06
  • Also, most apis will fail for localhost. This would mostly work when you host it on a url. So, if that is the case, you could have the response taken from your web browser and then save the json file as a mock response in your project. Then, have the axios call return this mock service – Shahin Nazer Jun 27 '22 at 07:44
  • @pe.Math You can refer to [NextJs CORS issue](https://stackoverflow.com/questions/65058598/nextjs-cors-issue) for solutions on how to get around the CORS error in Next.js. – juliomalves Jun 27 '22 at 17:43
  • @juliomalves I already tried to solve this problem, but nothing worked. That's what Shahin said, the API I tried to access was not accepting other domains, so I had to create a JSON to read the data from my own API within the project. – pe.Math Jun 27 '22 at 17:46