Files
edx-platform/lms/static/js/discovery/models/search_state.js
John Hensley 1bb7db9925 Improve search error messages
When a more specific error message is available from the search backend,
show the user that instead of a blanket "There was an error, try
searching again."

In github.com/edx/edx-search, we're proposing removing quotes from the
list of reserved characters in Elastic search terms. This enables
searching for exact phrases, but also introduces the possibility of
malformed queries. In those cases, it would be nice to give the user a
hint that they need to change their query, instead of simply trying the
same one again.
2018-06-14 18:59:05 +05:30

146 lines
5.0 KiB
JavaScript

(function(define) {
define([
'underscore',
'backbone',
'js/discovery/models/course_discovery',
'js/discovery/collections/filters'
], function(_, Backbone, CourseDiscovery, Filters) {
'use strict';
return Backbone.Model.extend({
page: 0,
pageSize: 20,
searchTerm: '',
terms: {},
jqhxr: null,
initialize: function() {
this.discovery = new CourseDiscovery();
this.listenTo(this.discovery, 'sync', this.onSync, this);
this.listenTo(this.discovery, 'error', this.onError, this);
},
performSearch: function(searchTerm, otherTerms) {
this.reset();
this.searchTerm = searchTerm;
if (otherTerms) {
this.terms = otherTerms;
}
this.sendQuery(this.buildQuery(0));
},
refineSearch: function(terms) {
this.reset();
this.terms = terms;
this.sendQuery(this.buildQuery(0));
},
loadNextPage: function() {
if (this.hasNextPage()) {
this.sendQuery(this.buildQuery(this.page + 1));
}
},
// private
hasNextPage: function() {
var total = this.discovery.get('totalCount');
return total - ((this.page + 1) * this.pageSize) > 0;
},
sendQuery: function(data) {
this.jqhxr && this.jqhxr.abort();
this.jqhxr = this.discovery.fetch({
type: 'POST',
data: data
});
return this.jqhxr;
},
buildQuery: function(pageIndex) {
var data = {
search_string: this.searchTerm,
page_size: this.pageSize,
page_index: pageIndex
};
_.extend(data, this.terms);
return data;
},
reset: function() {
this.discovery.reset();
this.page = 0;
this.errorMessage = '';
},
onError: function(collection, response, options) {
if (response.statusText !== 'abort') {
this.errorMessage = response.responseJSON.error;
this.trigger('error');
}
},
onSync: function(collection, response, options) {
var total = this.discovery.get('totalCount');
var originalSearchTerm = this.searchTerm;
if (options.data.page_index === 0) {
if (total === 0) {
// list all courses
this.cachedDiscovery().done(function(cached) {
this.discovery.courseCards.reset(cached.courseCards.toJSON());
this.discovery.facetOptions.reset(cached.facetOptions.toJSON());
this.discovery.set('latestCount', cached.get('latestCount'));
this.trigger('search', originalSearchTerm, total);
});
this.searchTerm = '';
this.terms = {};
} else {
_.each(this.terms, function(term, facet) {
if (facet !== 'search_query') {
var option = this.discovery.facetOptions.findWhere({
facet: facet,
term: term
});
if (option) {
option.set('selected', true);
}
}
}, this);
this.trigger('search', this.searchTerm, total);
}
} else {
this.page = options.data.page_index;
this.trigger('next');
}
},
// lazy load
cachedDiscovery: function() {
var deferred = $.Deferred();
var self = this;
if (this.cached) {
deferred.resolveWith(this, [this.cached]);
} else {
this.cached = new CourseDiscovery();
this.cached.fetch({
type: 'POST',
data: {
search_string: '',
page_size: this.pageSize,
page_index: 0
},
success: function(model, response, options) {
deferred.resolveWith(self, [model]);
}
});
}
return deferred.promise();
}
});
});
}(define || RequireJS.define));