Reputation: 1109
I'm trying to implement a select2 search to dynamically produce results based on the users inputted data.
As the user is typing, it should send a GET request to an action that runs the query against ElasticSearch, ElasticSearch should then return a number of objects which I can convert into JSON.
I'm not seeing any results being displayed underneath the select2 searchfield, eventhough the query is being executed against ElasticSearch, and it's returning results based on the users data.
DashboardController.rb
def card_search
if params[:query].present?
cards = Elasticsearch::Model.search(params[:query]).records.first(1)
hash = {}
hash["results"] = cards.map{|v| v.serializable_hash(only: [:name]) }
render json: hash.to_json
else
render json: []
end
end
dashboard.html.erb
$(".js-data-example-ajax").select2({
ajax: {
url: "/dashboard/card_search",
dataType: 'json',
type: "GET",
delay: 250,
data: function (term, page) {
return {
query: term,
page: page
};
},
formatResult: function (item) { return item.name; },
formatSelection: function (item) { return item.name; },
results: function (data, page) {
return data;
},
cache: true
},
placeholder: 'Search for a card',
minimumInputLength: 1,
});
Parameters are successfully passed into the controller from the javascript:
Parameters: {"query"=>"Charizard", "page"=>"1"}
ElasticSearch produces array of results which is converted into JSON:
"{\"results\":[{\"name\":\"Charizard\"}]}"
When ElasticSearch returns an array and the JSON is returned to the AJAX call, this error is produced:
Upvotes: 0
Views: 437
Reputation: 1109
Solved!
I realised I had my JSON in the wrong format even though I was following the official select2 documentation: https://select2.org/data-sources/formats
So instead of storing my data in a hash and then converting that to json.
I looped through my results from ElasticSearch and stored each result in an array. I then converted this array to json and then returned it back to the AJAX call.
def card_search
if params[:query].present?
cards = Elasticsearch::Model.search(params[:query]).records.first(1)
array = []
cards.each do |c|
array << c
end
render json: array.to_json
else
render json: []
end
end
I also had to change the way I format my results on the select2 initializer. I needed to loop through each data item, and specify the id and the text of each result so that select2 could display it.
results: function (data) {
var results = [];
$.each(data, function(index, item){
results.push({
id: item.id,
text: item.name
});
});
return {
results: results
};
},
Upvotes: 0