templateSelection is not receiving the same JSON data programmatically

Hello!

I’m using the approach found in: ‘/data-sources/ajax’ for multiple selections using ajax:
$(".js-example-data-ajax").select2({
ajax: {
url: “https://api.github.com/search/repositories”,
dataType: ‘json’,
delay: 250,
data: function (params) {
return {
q: params.term, // search term
page: params.page
};
},
processResults: function (data, params) {

}
placeholder: ‘Search for a repository’,
minimumInputLength: 1,
templateResult: formatRepo,
templateSelection: formatRepoSelection
});

It is working great when used interactively, templateSelection function is receiving as first parameter the JSON item from the ajax response. However, when I try to add selected options programmatically as shown in ‘/programmatic-control/add-select-clear-items’:
// Set up the Select2 control
$(’#mySelect2’).select2({
ajax: {
url: ‘/api/students’
}
});

// Fetch the preselected item, and add to the control
var studentSelect = $(’#mySelect2’);
$.ajax({
type: ‘GET’,
url: ‘/api/students/s/’ + studentId
}).then(function (data) {
// create the option and append to Select2
var option = new Option(data.full_name, data.id, true, true);
studentSelect.append(option).trigger(‘change’);

//Other listeners will in fact receive params.data correctly; however, templateSelection will not
studentSelect.trigger({
type: ‘select2:select’,
params: {
data: data
}
});
});

Then, templateSelection receives as ‘data’ parameter an standard JSON:{ disabled: false
element: option
id: “11898”
selected: true
text: “option text”
title: “”
_resultId: “select2–result-8vg3-11898”}

Instead of the actual data returned in the ajax call.

How can I add an option programmatically in such a way the same behavior as when used interactively is replicated and templateSelection gets the ajax returned ‘data’ as parameter?

I have reproduced the issue you reported. And in fact, even if you select the inserted item via the Select2 UI (i.e., open the dropdown and click on the inserted item), the data the templateSelection callback gets is the “standard” object, not the data object you passed in the triggered select2:select event.

Note that the manually inserted item gets added to the Select2’s internal list of data items when the change event is triggered. At that point, it only has the contents of the inserted Option object to generate the new data item. This is different from the data value that gets passed to the manually triggered select2:select event handler. So I’m not sure this is a “bug” per se, but it’s certainly not expected.

If you’re looking for a way to work around this, and assuming there’s “extra” data in the inserted item that you want to use in your templateSelection callback, you could attach that extra data to the Option element (e.g., in its dataset property), and then use the element property of the data object passed to the templateSelection callback. You can distinguish the data object for a manually inserted item by the presence of the _resultId property (which is not present in the items that come from the AJAX result).