I am using the Bing Web Search API, and I am accessing the data when typing a query into the search bar I created. But I have not been able to get the data to display in my search results when submitting the search bar query. I am trying to access the elements in 'value' which is inside of 'webPages' as shown in the picture below: [search engine data]: https://i.sstatic.net/CRBjB.png
Bing Web Search: https://learn.microsoft.com/en-us/bing/search-apis/bing-web-search/reference/endpoints
If anyone could help with a detailed response it would be greatly appreciated!
useSearch.js:
import { useState, useEffect } from 'react';
import axios from 'axios';
const BASE_URL = 'https://api.bing.microsoft.com/v7.0/search';
const API_KEY = '0760f20a58f340a4ba3ce10857c43142'
const useSearch = ( {searchTerm} ) => {
const [data, setData] = useState('');
useEffect(() => {
const fetchData = async () => {
if (!searchTerm) return;
try {
const response = await axios.get(`${BASE_URL}`, {
headers: {
'Ocp-Apim-Subscription-Key': API_KEY,
},
params: {
'q': `${searchTerm}`,
'count': 10,
'mkt': 'en-us',
},
});
setData(response.data.webPages.value);
// shows data from search bar
console.log(response.data);
} catch (error) {
console.error('Error fetching data:', error);
}
};
fetchData();
}, [searchTerm]);
return data;
};
export default useSearch;
SearchResults.js:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import TileItems from './TileItems';
import useSearch from './UseSearch';
const SearchResults = () => {
const [theme, setTheme] = useState('light');
const { data } = useSearch({ searchTerm: searchData });
return (
<div className=''>
<main className={`main-container ${theme}`}>
<section className="eighty" id="item-tiles">
<h1>Search Results</h1>
{data ? (
<ul>
{data.map((i) => (
<TileItems
key={i.id}
image={i.thumbnailUrl}
title={i.name}
description={i.snippet}
website={i.url}
/>
))}
</ul>
) : (
<p>Loading...</p>
)}
</section>
<section id="item-tiles-right" className="twenty">
<h2 id='col-2-header'>News</h2>
{video ? (
<ul>
{/* this section is still under development */}
{video.map((v) => (
<iframe
id='ytplayer'
src={v.contentUrl}
frameborder='0'
allow='autoplay; encrypted-media'
width='100%'
height='360'
title='video'
/>
))}
</ul>
) : (
<p>Loading...</p>
)}
</section>
</main>
</div>
);
};
Nav.js:
import React, { useState } from 'react';
import './NavBar.css';
import logo_light from '../../assets/spigot-logo.png';
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';
import useSearch from '../UseSearch';
function NavBar({theme, setTheme, setSearchTerm}) {
const [searchQuery, setSearchQuery] = useState('');
const { data } = useSearch({ searchTerm: searchQuery});
// console.log(setSearchQuery);
/* 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'>
<form>
<input className='search-bar' type='text' placeholder='Search' onChange={(e) =>
setSearchQuery(e.target.value)}></input>
</form>
<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
The data returned from useSearch
needs to be an array in order for you to map it, so in your useSearch
hook you need to only get the value
array if you want to only render the results.
// in useSearch hook
// we only take the array of webpages value
// looking from your console.log screenshot
setData(response.data.webPages.value);
You are trying to map your searchData
which is a string. In order for you to map the actual api data you would need to use the data returned from your useSearch
hook
// this is the API data
// no need to destruct
const data = useSearch({ searchTerm: searchData });
// replace searchData with data
{data ? (
<ul>
{data.map((i) => (
<TileItems
key={i.id}
image={i.thumbnailUrl}
title={i.name}
description={i.snippet}
website={i.url}
/>
))}
</ul>
) : (
<p>Loading...</p>
)}
Lemme know if this fixes your problem