javascriptreactjsaxiosgetsoda

Axios.get returns status code 400 cant figure out whats wrong (SODAapi)


Cant figure whats wrong with my axios call. Any help would be much appreciated.

So I have a search bar onClick that will send search terms to a function that compile the Api query string.

const SearchForm = () => {
  const [searchTerm, setSearchTerm] = useState({
    searchTerm : "",
    boro: ""
  });

  const handleChange = e => {
    const { value, name }  = e.target;    
    setSearchTerm((e)=>{
      return {
        ...searchTerm,
        [name] : value
      }
    });
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    debugger
    const res = await SodaApi.searchResta(searchTerm.searchTerm, searchTerm.boro);
    console.log(res)
    setSearchTerm("");
  }

  return (
    <form className="SearchForm" onSubmit={handleSubmit}>

        <label htmlFor="searchBar">Restaurant Name:</label>
        <input type="text"
              id="searchBar"
              name="searchTerm"
              placeholder="Enter Restaurant Name"
              value={searchTerm.searchTerm}
              onChange={handleChange}       
        />        

        <label htmlFor="boro">Borough: <span>*</span></label>
        <select id="boro" 
                name="boro"
                value={searchTerm.boro}
                onChange={handleChange}
                required
        > 
          <option value="" defaultValue disabled hidden>Select a Boro</option>
          <option value="Brooklyn">Brooklyn</option>
          <option value="Manhattan">Manhattan</option>
          <option value="Staten Island">Staten Island</option>
          <option value="Bronx">Bronx</option>
          <option value="Queens">Queens</option>
        </select>        
   
        <button className="SearchFormButton" type="submit">Search</button>      
    </form>
  )
}

export default SearchForm;

Heres the compile function

class SodaApi {
  static token;

  static async searchResta (searchTerm, boro) {
    const headerOptions = {
      headers : {
        'X-App-Token' : `${config.MY_APP_TOKEN}`
      }
    };

    const queryOptions = `$query=SELECT camis,dba,boro,building,street,zipcode,phone,cuisine_description,inspection_date,action,violation_code,violation_description,critical_flag,score,grade,grade_date,record_date,inspection_type,latitude,longitude WHERE dba like '%${searchTerm.toUpperCase()}%' AND boro = '${boro}'`;
    const sodaApiQueryString = config.NYC_RESTA_API_URL + queryOptions;
    const results = await axios.get( sodaApiQueryString, headerOptions);
    const cleanedResults = consolidate(results);


    return cleanedResults
  };

This is the sample query string I get back. Im calling to a Soda Api.

https://data.cityofnewyork.us/resource/43nn-pn8j.json?$query=SELECT%20camis,dba,boro,building,street,zipcode,phone,cuisine_description,inspection_date,action,violation_code,violation_description,critical_flag,score,grade,grade_date,record_date,inspection_type,latitude,longitude%20WHERE%20dba%20like%20%27%STAR%%27%20AND%20boro%20=%20%27Brooklyn%27

The error Im getting back is this

GET https://data.cityofnewyork.us/resource/43nn-pn8j.json?$query=SELECT%20camis,dba,boro,building,street,zipcode,phone,cuisine_description,inspection_date,action,violation_code,violation_description,critical_flag,score,grade,grade_date,record_date,inspection_type,latitude,longitude%20WHERE%20dba%20like%20%27%STAR%%27%20AND%20boro%20=%20%27Brooklyn%27 400 (Bad Request)


Uncaught (in promise) Error: Request failed with status code 400
    at createError (createError.js:16)
    at settle (settle.js:17)
    at XMLHttpRequest.handleLoad (xhr.js:62)

What I don't get is If I sent this same query string inside INSOMNIA I get status code 200 and I get the data that I want. But How come When sent it with my search bar I get back a 400 error. I tried taking out my header token, I tried searching with a different query. Again my app doesn't work but If I take that same query string I get back from my chrome console and sent it with INSOMNIA it works.

How Come??


Solution

  • The % characters in your query string aren't being encoded properly. They should be encoded as %25. See https://developers.google.com/maps/documentation/urls/url-encoding

    The easiest way to ensure this with Axios is to use the params config. Any keys / values in there will be URL encoded.

    const options = {
      headers : {
        'X-App-Token': config.MY_APP_TOKEN
      },
      params: {
        "$query": `SELECT camis,dba,boro,building,street,zipcode,phone,cuisine_description,inspection_date,action,violation_code,violation_description,critical_flag,score,grade,grade_date,record_date,inspection_type,latitude,longitude WHERE dba like '%${searchTerm.toUpperCase()}%' AND boro = '${boro}'`
      }
    };
    
    const results = await axios.get(config.NYC_RESTA_API_URL, options);