Closed srinivas025 closed 5 years ago
Hello @srinivas025,
Please try the below attached file, it has a quick fix and let me know how it went.
Hi, firstly thanks for the great package. The file you sent lastly works for me to fix duplicated api calls. But 'afterend', 'ul' elements rendering more than once. For example if I type 4 times , it renders 4 different ul elements with id is 'autoComplete_results_list'. Any idea ?
Hello @argebynogame,
Thanks, man!
Great, I'm glad that we've solved the first issue api multiple calls
.
Find the fixed build here
Let's check the second one.
Just kindly provide the below details to help replicate your issues.
autoComplete.js
code snippetCheers! :)
Hello again @TarekRaafat , I will drop some screenshots and code snippet , I hope it works :) When I typed 'germ' , it finds Germany but every time when i type a letter new 'ul' element created. And there is no console error. Thanks in advance :)
document.querySelector("#autoComplete").addEventListener("keyup", function(event) {
const query = document.querySelector("#autoComplete").value;
if (query !== '') {
const autoCompletejs = new autoComplete({
data: { // Data src [Array, Function, Async] | (REQUIRED)
src: async () => {
// API key token
// const token = "this_is_the_API_token_number";
// User search query
const query = document.querySelector("#autoComplete").value;
// Fetch External Data Source
const source = await fetch(`https://restcountries.eu/rest/v2/name/${query}`);
// Format data into JSON
let data = await source.text();
// console.log(data);
data = JSON.parse(data);
// Return Fetched data
return data;
},
key: ["name"],
cache: true
},
// query: { // Query Interceptor | (Optional)
// manipulate: (query) => {
// return query.replace("pizza", "burger");
// }
// },
sort: (a, b) => { // Sort rendered results ascendingly | (Optional)
if (a.match < b.match) return -1;
if (a.match > b.match) return 1;
return 0;
},
placeHolder: "Please type something ?", // Place Holder text | (Optional)
selector: "#autoComplete", // Input field selector | (Optional)
threshold: 1, // Min. Chars length to start Engine | (Optional)
debounce: 600, // Post duration for engine to start | (Optional)
searchEngine: "strict", // Search Engine type/mode | (Optional)
resultsList: { // Rendered results list object | (Optional)
render: true,
container: (source) => {
const resultsListID = "search_List";
source.setAttribute("id", "autoComplete_results_list");
return resultsListID;
},
destination: document.querySelector("#autoComplete"),
position: "afterend",
element: "ul"
},
maxResults: 10, // Max. number of rendered results | (Optional)
highlight: true, // Highlight matching results | (Optional)
resultItem: { // Rendered result item | (Optional)
content: (data, source) => {
let html = `<div class="d-flex align-items-center flex-row"><span><img width="60" alt="${data.match}" src="${data.value.flag}"></span> <span style="margin-left: 2em;">${data.match}</span></div>`;
$(source).html(html);
},
element: "li"
},
// noResults: () => { // Action script on noResults | (Optional)
// const result = document.createElement("li");
// result.setAttribute("class", "no_result");
// result.setAttribute("tabindex", "1");
// document.querySelector("#autoComplete_results_list").appendChild(result);
// },
// onSelection: feedback => { // Action script onSelection event | (Optional)
// console.log(feedback.selection.value.image_url);
// }
});
}
});```
Try removing the below lines and let me know how it went.
document.querySelector("#autoComplete").addEventListener("keyup", function(event) {
const query = document.querySelector("#autoComplete").value;
if (query !== '') {
Hey, if I remove these lines autoComplete try to run without a search query then it fails . it is a data.json() error :) And then I try to search nothing happen because of error.
Hi @TarekRaafat,
I used the used that you sent above and seeing an error on key press.
Uncaught TypeError: _this2.dataSrc.then is not a function
at run (autocomplete.js:365)
at HTMLInputElement.
Hello @srinivas02,
If you're using this.dataSrc
it's changed to this.dataStream
.
If not please provide the below details to help replicate your issue.
Cheers! :)
@TarekRaafat
I used the new fixed code and getting the error
Uncaught TypeError: Cannot read property 'then' of undefined
at run (autocomplete.js:365)
at HTMLInputElement.
var autoCompletejs = new autoComplete({
data: {
src: async function() {
// Loading placeholder text
if($("#autoComplete").is(':focus')){
console.log("focus");
$areaDocsSearch.find('.img-loader').show();
}
const query = document.querySelector("#autoComplete").value;
if (query.length == 1){
$areaDocsSearch.find('#autoComplete_results_list').removeClass('back-drop');
}
document
.querySelector("#autoComplete")
.setAttribute("placeholder", "Loading...");
const source = await fetch(
"/Help/searchReadme?search="+query
);
let results = source.results;
const data = await source.json();
// Post loading placeholder text
document
.querySelector("#autoComplete")
.setAttribute("placeholder", "Search help docs");
return data.results;
},
key: ["title"],
cache: false
},
sort: (a, b) => {
if (a.match < b.match) return -1;
if (a.match > b.match) return 1;
return 0;
},
placeHolder: "Search help docs",
selector: "#autoComplete",
threshold: 0,
debounce: 300,
searchEngine: "strict",
highlight: true,
maxResults: 10,
resultsList: {
render: true,
container: source => {
source.setAttribute("id", "autoComplete_results_list");
},
destination: document.querySelector("#form_docs_search"),
position: "afterend",
element: "ul"
},
resultItem: {
content: (data, source) => {
$areaDocsSearch.find('.img-loader').hide();
source.innerHTML = data.match;
if ($areaDocsSearch.find('#autoComplete_results_list li').length == 0){
$areaDocsSearch.find('#autoComplete_results_list').removeClass('back-drop');
}
else{
$areaDocsSearch.find('#autoComplete_results_list').addClass('back-drop');
}
},
element: "li"
},
noResults: () => {
const result = document.createElement("li");
$areaDocsSearch.find('#autoComplete_results_list').removeClass('back-drop');
result.setAttribute("class", "no_result");
result.setAttribute("tabindex", "1");
result.innerHTML = "No Results";
document.querySelector("#autoComplete_results_list").appendChild(result);
$areaDocsSearch.find('.img-loader').hide();
},
onSelection: feedback => {
console.log(feedback)
const selection = feedback.selection.value.url;
window.open(selection, '_blank');
// Clear Input
document.querySelector("#autoComplete").value = "";
}
});
when i console logged _this2, i got this as response
data: cache: false key: ["title"] src: ƒ src() proto: Object dataStream: undefined dataType: true debounce: 300 highlight: true maxResults: 10 noResults: () => {…} onSelection: feedback => {…} placeHolder: "Search help docs" query: undefined resultItem: {content: ƒ, element: "li"} resultsList: {render: true, shadowRoot: document, view: ul#autoComplete_results_list, navigation: false} searchEngine: "strict" selector: "#autoComplete" sort: (a, b) => {…} threshold: 0 trigger: {event: Array(1), condition: false}
Hi @TarekRaafat I finally made it to work by changing the run function to this
var run = function run(event) {
if (!_this2.data.cache) {
_this2.dataStream = _this2.data.src();
_this2.dataType = _this2.dataStream instanceof Promise;
if (_this2.dataType) {
_this2.dataStream.then(function (response) {
_this2.dataStream = response;
exec(event);
});
} else {
_this2.dataStream = _this2.dataStream;
exec(event);
}
} else {
exec(event);
}
};
@argebynogame try this code and let me know how it went.
const autoCompletejs = new autoComplete({
data: {
src: async function () {
// Fetch External Data Source
const source = await fetch("https://restcountries.eu/rest/v2/all");
// Format data into JSON
const data = await source.json();
// Return Fetched data
return data;
},
key: ["name"],
},
});
@srinivas025 did you try first to switch the cache
to true?
@TarekRaafat i dont want to cache the data because i dont have a call to get all results.
Hello @srinivas025 & @argebynogame,
I've entirely re-factored the data handling section.
Now the data.src
never calls theAPI
if set not to be cached until you start typing in-order to provide the API
a query.
Previously it used to initiate empty API
calls that caused that issue in addition to a bug that existed in the non-cached data.src
that has been solved as well thanks to @braco.
Kindly check the new build it should work as expected and let me know how it went.
Cheers! :)
Hi, i found an issue when querying in the input box. When i do a keypress, my api is called 2 times which is present in data.src async function. this makes the user experience slow since the search results are not rendered unless i get response from the second call. Please let me know how i can fix this. Thanks