How to Use Searchbar for API'S

How to display API data by entering a postcode into a search bar?

Might have missed the mark - but you just want to have the data call out for whatever is currently typed into the search field right? If so this should do it - just need to make a few element references and expose the end of the url for updates.

<input id="mySearchField" name="search" placeholder="Search.." type="text">

<button id="mySearchButton">Search</button>
<div id="myContentArea></div>

<script>

$(function() {
var _myContentArea = document.getElementById("myContentArea");
var _mySearchButton = document.getElementById("mySearchButton");
_mySearchButton.onclick = getData;

function getData(){
var _mySearchField = document.getElementById("mySearchField");
$.ajax({
url: "http://api.lmiforall.org.uk/api/v1/census/jobs_breakdown?area="+_mySearchField.value,
method: "GET",
dataType: "json",
success: function(data) {
var str = "";
for(var i= 0; i < data.jobsBreakdown.length; i++){

str +='Job Title : '+data.jobsBreakdown[i].description+' <br> Total Number of People Engaged in Occupency : '+data.jobsBreakdown[i].value+' <br> Percentage of Occupancies in Area : '+data.jobsBreakdown[i].percentage.toPrecision(2)+'% <br><br>';
}
_myContentArea.innerHTML = str;
}
});
}

});
</script>

How to use SearchBar for API's?

Well if you want to do things right, you should use a reactive framework. Most people are hot on ReactiveCocoa right now, but a lot of people also use RxSwift. I am more of a RAC guy so I will point you in that direction.

Colin Eberhardt wrote a blog post about making an app that does basically this exact thing with twitter searching. He also has another similar RAC flickr app. He uses RAC3 which is only slightly different (mostly syntax changes) from RAC4. I would highly suggest learning about and beginning to implement Functional Reactive techniques in your apps.

Cheers!

Search Bar with API database

You are using the same state for the data you receive and the value is input in the SearchBar, first create another state to keep the input value and pass that in the URL

export class Diet extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
searchValue: '',
};
}

updateSearch = (value) => {
this.setState({searchValue: value})
axios
.get(
`https://api.spoonacular.com/food/products/search?apiKey{1234}&query=${value}&number=100`
)
.then((res) => {
this.setState({ data: res.data });
})
.catch((error) => {
console.log(error.response.data);
});
};

render() {
return (
<>
<SearchBar
placeholder="Search Food..."
onChangeText={this.updateSearch}
value={searchValue}
/>
<List style={{ paddingTop: hp("2%") }}>
<TouchableOpacity>
{this.state.data.map(({ type }) => (
<Text>{this.state.type.products.title}</Text>
))}
</TouchableOpacity>
</List>
</>
);
}
}

However, doing this every time the user types is not recommended, you can check out this pattern to debounce the API call for usability https://gist.github.com/simonw/c29de00c20fde731243cbac8568a3d7f

UPDATE

Since the API doesn't allow to search for empty value, put a condition to set the data to an empty array when the input is blank

  updateSearch = (value) => {
this.setState({searchValue: value})
if(value.trim() !== '') {
axios
.get(
`https://api.spoonacular.com/food/products/search?apiKey{1234}&query=${value}&number=100`
)
.then((res) => {
this.setState({ data: res.data });
})
.catch((error) => {
console.log(error.response.data);
});
} else {
setState({data: []})
}
};

How do I implement APIs in a search bar on VueJS?

I believe all the problems with the search bar have been solved: Demo here

I added comments to the code so it should be clear how it works.

In searchbar.vue:

<template>
<v-autocomplete
clearable
:loading="isLoading"
:items="games"
:search-input.sync="search"
hide-details
item-text="name"
item-value="id"
label="Search for a Game..."
solo-inverted
></v-autocomplete>
</template>

<script>
import _ from "lodash";

export default {
data: () => ({
games: [], // this is where all the game data will be stored
isLoading: true, // variable to determine if the results are still being fetched from the API
search: null // this is where the query will be stored
}),
methods: {
getGames(params = "") {
// this function will fetch game data from https://api.rawg.io/api/games with whatever api parameters you pass to the parameter `params`
this.axios
.get("https://api.rawg.io/api/games" + params)
.then(resp => {
// fetch data
let tempGames = [...this.games.slice(0), ...resp.data.results]; //copy of this.games + new data
this.games = _.uniqBy(tempGames, "id"); // remove any duplicates
this.isLoading = false; // now that the data is in the array `games`, we can set isLoading to false
})
.catch(e => {
// code to run if there was an error
console.error(e); // display error message
});
},
searchGames(query) {
// this function will call getGames() with the search query formatted as an API parameter (?search=YOUR_QUERY)
let searchQuery = encodeURI("?search=" + query); // URI encode the query so it is able to be fetched properly
this.getGames(searchQuery);
}
},
watch: {
search: _.debounce(function(query) {
// debounce with a a value of 250 will allow this function to be every 250 milliseconds at most. So if the user is typing continually, it won't run until the user stops.
this.searchGames(query);
}, 250)
},
created() {
this.getGames(); // load the first 20 games initally
}
};
</script>

This will:

  1. Load the first 20 games
  2. When you enter a query and stop typing, it will perform a request to https://api.rawg.io/api/games?search=YOUR_QUERY, and add the results to the games array. (So each time you search for something, the saved games array increases. That means that if you search for the same game twice, while it will still search online with https://api.rawg.io/api/games?search=YOUR_QUERY, the game will have been already in the games array from the first time, so it will be loaded immediately.)
  3. v-autocomplete filters and displays the results.

This method will work better on faster connections, as the results are loaded faster. So if you have a slow connection, it may take time for the results to load. Unfortunately that's something that can't be worked around (although you could load a lot of data beforehand, but there's no guarantee that what you load is what the user will search for)

The graphical problem with the navbar was resolved by changing the parent <div> in App.vue to <v-app>, like so:

Before:

<template>
<div id="app">
<nav-bar></nav-bar>
...
</div>
</template>

After:

<template>
<v-app id="app">
<nav-bar></nav-bar>
...
</v-app>
</template>

I also added lodash as a dependency for debouncing (waiting until the user stops typing) and removing duplicates.

Here's the codepen I was working on.

Do let me know if you have any further questions.



Related Topics



Leave a reply



Submit