-
Notifications
You must be signed in to change notification settings - Fork 44
Description
When searching on BigCommerce, the search function can be called multiple times, but subsequent calls will not cause previous in-flight calls to be canceled. This creates a problem because any UI component, even the default theme, will call this API and will get the responses out-of-order. Thus, the rendered quick-list is not guaranteed to show the results that match what is in the search box.
Here is a real-life example:
You can see the results of the search for "1" returned after nearly 4 seconds. I can easily type the entire number in 4 seconds. In fact, the last search is .6 seconds. So, as long as I can type the number in <3.4 seconds, I'll get my result for the full number, and it will render, before the result for the first number returns. So, in that case, the search results list that shows will always show the results for the first search for "1" before the results for "100000"
This is an easy fix. You could use an AbortController.
For example, that search.js that I linked to above could be replaced this this:
import Hooks from '../hooks';
import Base from './base';
export default class extends Base {
/**
* @Constructor
*/
constructor(version) {
// call parent
super(version);
// set up class variables
this.endpoint = '/search.php?search_query=';
this._searchController = null;
}
/**
* Get search results
* @param {String} query
* @param {Object} params
* @param {Function} callback
*/
search(query, params, callback) {
const url = this.endpoint + encodeURIComponent(query);
let paramsArg = params;
let callbackArg = callback;
if (typeof paramsArg === 'function') {
callbackArg = paramsArg;
paramsArg = {};
}
if (this._searchController) {
this._searchController.abort();
}
this._searchController = new AbortController();
paramsArg.signal = controller.signal;
Hooks.emit('search-quick-remote', query);
this.makeRequest(url, 'GET', paramsArg, false, callbackArg);
}
}Of course, then you'd have to modify /lib.request.js to be like this:
const config = {
method: options.method,
headers,
credentials: 'include',
signal: options.signal,
};This is a real-world problem affecting clients. For example, see BigCommerce issue STRF-13076. If you'd like a PR for this, please let me know and I'll put one up for you.
