-1

I am attempting to adapt this tutorial to obtaining data from this url: https://en.wikipedia.org/w/api.php?action=query&list=prefixsearch&format=json&pssearch=/ufc

The request functions correctly and obtains the response. However, if I do console.log(options);. The console shows the options variable as empty. What am I doing wrong?

On a similar and more illustrative note, if I do the below. The output is always false.

        setLoading(false);
        console.log(loading);
        setLoading(true);
        console.log(loading);
        setLoading(false);
        console.log(loading);

The request

import axios from 'axios';

const url = axios.create({
    baseURL: 'https://en.wikipedia.org/w/api.php?origin=*&action=query&list=prefixsearch&format=json&pssearch=',
    headers: {'Api-User-Agent':'EventGator (http://xxx.xxx.xxx.xxx:8080)'}
});

export const getApiSuggestions = (title) => {
    let result = url
        .get(`${title}`)
        .then((response) => {
            return response.data;
        })
        .catch((error) => {
            return error;
        });
    console.log(result);
    return result;
};

The search page

import React, {useContext, useState, useEffect} from "react";
import {SearchContext} from "../../contexts/SearchContext"
import { getApiSuggestions } from './requests';
import SearchInput from './SearchInput';
import { MainWrapper } from './style';
import "../../App.css"


export function Search (){

const [options, setOptions] = useState({matches:[]});
const [loading, setLoading] = useState(false);

const getSuggestions = async (title) => {
    if (title) {
        setLoading(true);
        let response = await getApiSuggestions(title);
        setOptions({matches:response.query.prefixsearch}); //This doesn't appear to save into options:matches

        setLoading(false);
        console.log(response.query.prefixsearch); //this provides the json result set to console.
        console.log(options);                     //this doesn't
    } else {
        setOptions([]);
    }
};

const getApiUrl = (url) => {
    window.open(url, '_blank');
};

    return (
      <div>
      <div className="search container">
      <div className="input-group input-group-sm mb-3 center">
            <MainWrapper className="form-control center">
                <SearchInput
                    loading={loading}
                    options={options}
                    requests={getSuggestions}
                    onClickFunction={getApiUrl}
                    placeholder="Search for a wikipedia title"
                />
            </MainWrapper>
            </div>
            </div>
      </div>
    );

}
export default Search;

The Output from:

console.log(response.query.prefixsearch)

[{ns: 0, title: "UFC 264", pageid: 67197876}, {ns: 0, title: "UFC Rankings", pageid: 55036039}, {ns: 0, title: "UFC on ESPN: Makhachev vs. Moisés", pageid: 67783350}, {ns: 0, title: "UFC 229", pageid: 56175506}, {ns: 0, title: "UFC 265", pageid: 67410930}, {ns: 0, title: "UFC 266", pageid: 67397733}, {ns: 0, title: "UFC on ESPN: Sandhagen vs. Dillashaw", pageid: 67577861}, {ns: 0, title: "UFC 257", pageid: 65611292}, {ns: 0, title: "UFC 205", pageid: 50527598}, {ns: 0, title: "UFC 200", pageid: 48625599}]
TheMightyLlama
  • 1,243
  • 1
  • 19
  • 51
  • Does this answer your question? [useState set method not reflecting change immediately](https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately) – Aleksandr Smyshliaev Jul 24 '21 at 15:18

1 Answers1

0

useState and setState are async, they get executed not instantly.

Can use Promises for that

const getSuggestions = (title = '') => {
        if (!title) { 
          return false
        }
        setLoading(true);
        getApiSuggestions(title)
           .then(response => 
             setOptions({ matches:response.query.prefixsearch });
           )
           .catch(error => {
              console.warn(error)
              return error
            })
           .finally(() => setLoading(false))
};