Web Development

Creating a search function – JavaScript – SitePoint Forums


Hi there I am working on the marvel Api, i have managed to extract data but now i want to create a search function whereby only those characters from the api are returned that include my search term, i have been playing around with it for a bit but not been successful yet, any ideas please help.

import './style.css'

import javascriptLogo from './javascript.svg'

import viteLogo from '/vite.svg'

import { setupCounter } from './counter.js'

import md5 from 'md5'

const publicKey = 'd73f66f08c7d56dde7aaf6ded4a26718';

const privateKey = '9d331bbe217eebffed1c66f8e3fe0a6818845b87';

let timestamp = new Date().getTime()

let hashVal = md5(timestamp+privateKey+publicKey);

const url = `http://gateway.marvel.com/v1/public/characters?ts=${timestamp}&apikey=${publicKey}&hash=${hashVal}&limit=100`;

const button = document.getElementById('submit-search');

const searchInput = document.getElementById('search-input')

let characters = []
button.addEventListener('click', ()=>{
   fetch(url).then(response=> response.json().then(data=>{
    let characters = data.data.results;
    console.log(characters)
     searchQuery()
    //  displayData()
   }))

})

function searchQuery(){
  const searchTerm =  searchInput.value.trim().toLowerCase()
   const filteredResult = characters.filter((character)=>{
    const characterName  = character.name.toLowerCase()
    if(characterName.includes(searchTerm)){
      return characterName
    }else 'no match found'
   })
  //  console.log(filteredResult)
}



// function displayData(){
//   const resultsContainer = document.getElementById('results-container')

  
//     characters.forEach(character =>{
//       console.log(character)
//       const characterDiv = document.createElement('div')
//       resultsContainer.appendChild(characterDiv)
//       characterDiv.classList.add('character')

//       const charName = document.createElement('h2')
//       charName.textContent = character.name
//       characterDiv.appendChild(charName)
//       let image = document.createElement('img')
//       image.classList.add('results-image')
//       image.src = `${character.thumbnail.path + '.'}${character.thumbnail.extension}`
//       characterDiv.appendChild(image)
      
//     })

  // }else {
  //   const noResultsMessage = document.createElement('p');
  //   noResultsMessage.textContent="No results found";
  //   resultsContainer.appendChild(noResultsMessage);
  // }
  
// }

some of the code has been commented out as i am just focussing on the searchQuery function dont think i can get it to do what i want

You should use indexOf instead of include. Then it should work



1 Like

this is returning all the api results and then an empty array, i want to show only api results that contain my my search input so for exapmple if i search ‘men’ then i want a list of all characters that contain men

Opinionated I know, but the first thing I would do would be rename that function and call it something like getMatchingCharacters or getMatchingChars. ‘searchQuery’ is a bit vague to me, and doesn’t tell me what the function does.

I would change it so that it took two arguments, a search term and the characters array. That way you aren’t relying on globals, and hunting through your code to find where these variables originate from.

The other benefit is that you are able to test it as a standalone function.

function getMatchingChars(searchTerm, characters) {
  const searchToLower = searchTerm.trim().toLowerCase();
  // flatMap might be a better option here
  // this will return an array of only the matching characters
  const filteredResult = characters.flatMap((character) => {
    const characterName = character.name.toLowerCase();

    if (characterName.includes(searchTerm)) {
      return characterName;
    }

    return []; // this will be discarded by flatMap
  });
  //  console.log(filteredResult)
}

It looks like you want a mixture of filter and map to me, so I have swapped out what you have for flatMap

Example of flatMap.

const fruit = [ 'apple', 'banana', 'cherry', 'date', 'fig', 'grape' ];

fruit.flatMap((fruit) => {
  if (fruit.length === 5) {
    return fruit.toUpperCase();
  }
  return [];
})
// [ 'APPLE', 'GRAPE' ]

It might be helpful though if you could give us some sample JSON data, just to see what you are searching through, and some sample search terms.

the flatMap didnt work, this is the data i am getting from fetch

if i search zero i want to return any characters that contain zero



Source

Related Articles

Back to top button