jesse morris
jesse morris

Reputation: 5

How do I pass the api key with query into this get request in react using axios for bing web search api

I am trying to create a search bar with bing web api and having trouble figuring out how to pass the api key along with the search query into the get request using axios. Also how do I get the user input from the search bar into the get request. If someone could help out with a detailed answer I'd appreciate it very much!

https://learn.microsoft.com/en-us/bing/search-apis/bing-web-search/search-the-web

this is what I've tried:

import React, { useEffect, useState } from 'react';
import axios from 'axios';

// Search bar capabilities under development

const BASE_URL = 'https://api.bing.microsoft.com/v7.0/search'
const API_KEY = process.env.REACT_APP_SEARCH_KEY;


const useSearch = (searchTerm) => {
  const [data, setData] = useState(null);

const headers = {
  headers: {
    'Ocp-Apim-Subscription-Key:': 'API_KEY'
  }
}

const params = {
  headers: {
    'q': `${searchTerm}`,
    'count': 10,
    'mkt': 'en-us',
  }
}

  useEffect(() => {
    const fetchData = async () => {
      const response = axios.get(`${BASE_URL}`, headers=headers);
      setData(response?.data);
    };

    fetchData();
  }, [searchTerm])
  return {
    data,
  };
};


export default useSearch;

this is what my nav file looks like:

import React from 'react'
import './NavBar.css'
import logo_dark from '../../assets/logo_light2.png'
import search_icon_light from '../../assets/search-w.png'
import search_icon_dark from '../../assets/search-b.png'
import toggle_light from '../../assets/night.png'
import toggle_dark from '../../assets/day.png'



function NavBar({theme, setTheme}) {

  /* ternary clause to change theme between light and dark mode */
  const toggle_mode = () => {
    theme == 'light' ? setTheme('dark') : setTheme('light');
  }

  return (
    <div className='navbar' >
        <img src={theme == 'light' ? logo_light : logo_dark} alt='' className='logo' />
        <ul className='nav-list'>
          <li>SEARCH</li>
        </ul>
      <div className='search-box'>
        <input  className='search-bar' type='text' placeholder='Search'></input>
        <img className='search-icon' src={theme == 'light' ? search_icon_light : search_icon_dark} alt='' />
      </div>
      <img onClick={() => {toggle_mode()}} src={theme == 'light' ? toggle_light : toggle_dark} alt='' className='toggle-icon'></img>
    </div>
  )
}

export default NavBar

Upvotes: 0

Views: 219

Answers (1)

mssp
mssp

Reputation: 305

In your useSearch hook you need to do this. I added in comment codes explaining what I am doing and what I have changed

import React, { useEffect, useState } from "react";
import axios from "axios";

// Search bar capabilities under development

const BASE_URL = "https://api.bing.microsoft.com/v7.0/search";
const API_KEY = process.env.REACT_APP_SEARCH_KEY;

const apiAuthHeader = {
  "Ocp-Apim-Subscription-Key:": API_KEY,
};

// added named hook params for better readability 
const useSearch = ( {searchTerm} ) => {
  const [data, setData] = useState(null);
  // Just a suggestion for further improvements 
  // TODO: Debounce search
  // TODO: Add loading state and error handling
  useEffect(() => {
    // Every time the search term changes
    // it will create a new params object with a new
    // search term
    const searchParams = {
      q: `${searchTerm}`,
      count: 10,
      mkt: "en-us",
    };

    const fetchData = async () => {
      // supports options, so you can specify two options in your case,
      // headers for auth and params for your search params
      const response = axios.get(`${BASE_URL}`, {
        headers: apiAuthHeader,
        params: searchParams,
      });
      setData(response?.data);
    };
    // only call fetch data if the search term is not empty
   if (searchTerm)
    {
    fetchData();
    }
  }, [searchTerm]);

  return {
    data,
  };
};

I see you are not using your search hook anywhere, in your NavBar. Just remember you will have to add debouching as well not to spam the api with every key stroke. I suggest looking at debouching here, since debouching is not in the scope of the question. https://www.freecodecamp.org/news/debouncing-explained/

I did some minor modifications, and I am assuming data is an array, so you will have to render your data whoever you see fit. Also remember to do a check if there is data, otherwise nothing will render on initial fetch.

import React, { useState } from "react";
import "./NavBar.css";
// import your hook

function NavBar({ theme, setTheme }) {

  const [searchQuery, setSearchQuery] = useState("");
  // search query state is passed down to the hook
  const { data } = useSearch({ searchTerm: searchQuery });

  /* ternary clause to change theme between light and dark mode */
  const toggle_mode = () => {
    theme == "light" ? setTheme("dark") : setTheme("light");
  };

  return (
    <div className="navbar">
      <img
        src={theme == "light" ? logo_light : logo_dark}
        alt=""
        className="logo"
      />
      <ul className="nav-list">
        <li>SEARCH</li>
      </ul>
      <div className="search-box">
        <input
          onChange={(e) => setSearchQuery(e.target.value)}
          className="search-bar"
          type="text"
          placeholder="Search"
        />
        <img
          className="search-icon"
          src={theme == "light" ? search_icon_light : search_icon_dark}
          alt=""
        />
      </div>
      <img
        onClick={() => {
          toggle_mode();
        }}
        src={theme == "light" ? toggle_light : toggle_dark}
        alt=""
        className="toggle-icon"
      ></img>

      {data && <p>{data}</p>}
    </div>
  );
}

export default NavBar;

Upvotes: 0

Related Questions