ChasetopherB
ChasetopherB

Reputation: 464

Select2 gives error "Cannot read property 'results' of undefined"

I am trying to populate a searchable Select2 form-control with search results from Active Directory.

Here is my select2 function:

$("#networkUserSelect").select2({

    ajax: {
        url: '/Account/ADStartsWith',
        dataType: 'json',
        delay: 250,
        processResults: function (data, params) {
            return {
                results: $.map(data, function (item)
                /**http://api.jquery.com/jquery.map/ **/ {
                var name;
                var id;
                if (typeof (item.displayname) !== "undefined") {
                    name = (item.displayname["0"].replace("  ", " "));
                    id = (item.samaccountname["0"] + "@@email.com");
                    return {
                        text: name,
                        slug: name,
                        id: id
                    }
                }
                else {
                    console.log("display name undefined.");
                }
            })
        };
    },
    escapeMarkup: function (markup) { return markup; }, 
    minimumInputLength: 1
});

The url is pointing to a C# WebMethod that returns the Active Directory data as a JsonResult. Here is the JsonResult format as per Postman:

"results": [
        {
            "id": 1,
            "text": "XXX",
            "displayName": "XXX",
            "SAMAccountName": "XXX",
            "givenName": "XXX",
            "sn": "XXX",
            "company": "XXX"
        },
        {
            "id": 2,
            "text": "YYY",
            "displayName": "YYY",
            "SAMAccountName": "YYY",
            "givenName": "YYY",
            "sn": "YYY",
            "company": "YYY"
        }
    ]

The JSON is sent back to AJAX successfully. The processResults parameters contain the values that are expected.

At some point during the $.map portion, it invalidates the results and they become "undefined", and I get the error Cannot read property 'results' of undefined.

According to the Select2 documentation, my JSON is in the correct format.

I am not sure what I am missing.

Upvotes: 1

Views: 5936

Answers (3)

ewwink
ewwink

Reputation: 19154

you have typo it should be displayName & SAMAccountName and data to data.results and maybe the last item.displayName["0"] to item.displayName

$("#networkUserSelect").select2({
  ajax: {
    //url: '/Account/ADStartsWith',
    url: '//api.jsonbin.io/b/5af7d3a97a973f4ce5783c02',
    dataType: 'json',
    delay: 250,
    processResults: function(data, params) {
      return {
      	
        results: $.map(data.results, function(item) {
          var name;
          var id;
          if (typeof(item.displayName) !== "undefined") {
            name = (item.displayName.replace("  ", " "));
            id = (item.SAMAccountName + "@@email.com");
            return {
              text: name,
              slug: name,
              id: id
            };
          }
          else {
            console.log("display name undefined.");
          }
        })
      };
    },
    escapeMarkup: function(markup) {
      return markup;
    },
    minimumInputLength: 1
  }
});
.select2-container{width:300px !important}
<link href="https://select2.org/assets/7c647dd1b60ff2b17a493d7f00a18e26.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>

<select id="networkUserSelect"></select>

Upvotes: 0

diogenesgg
diogenesgg

Reputation: 2839

Actually there's a problem with your returned json. It should be fully enclosed with { }, like the following:

{"results": [
    {
        "id": 1,
        "text": "XXX",
        "displayName": "XXX",
        "SAMAccountName": "XXX",
        "givenName": "XXX",
        "sn": "XXX",
        "company": "XXX"
    },
    {
        "id": 2,
        "text": "YYY",
        "displayName": "YYY",
        "SAMAccountName": "YYY",
        "givenName": "YYY",
        "sn": "YYY",
        "company": "YYY"
    }
]}

Next, I'm not sure how you want to process the data being returned, but here is a working version of it:

$("#networkUserSelect").select2({

    ajax: {
        url: 'results.json',
        dataType: 'json',
        delay: 250,
        processResults: function (data, params) {
            return { 
                results: data.results.map(item => 
                    ({ 
                        text: item.displayName, 
                        id: item.SAMAccountName + "@email.com",
                        slug: item.displayName
                    })
                )}
        },
        escapeMarkup: function (markup) { return markup; }, 
        minimumInputLength: 1
    }
});

Once you get this working, maybe you should deal with filtering the data in the backend and passing the data param into request body, given that it contains the query filter and pagination attributes.

Upvotes: 0

Ritwick Dey
Ritwick Dey

Reputation: 19012

I think I got the problem. Please give a try. data is an object. data.result is the array which you're looking for.

EDIT: I found 2 more issue - typo in displayName & SAMAccountName.

`

$("#networkUserSelect").select2({

            ajax: {
                url: '/Account/ADStartsWith',
                dataType: 'json',
                delay: 250,
                processResults: function (data, params) {
                    return
                    {
                        /*
                             Pay attention here. `data.results`
                        */
                        results: $.map(data.results, function (item) 
                            /**http://api.jquery.com/jquery.map/ **/ {
                            var name;
                            var id;
                            if (typeof (item.displayName) !== "undefined") {
                                name = (item.displayName["0"].replace("  ", " "));
                                id = (item.SAMAccountName["0"] + "@@email.com");
                                return {
                                    text: name,
                                    slug: name,
                                    id: id
                                }
                            }
                            else {
                                console.log("display name undefined.");
                            }
                        })
                    };
                },
            },
            escapeMarkup: function (markup) { return markup; }, 
            minimumInputLength: 1
        });

Upvotes: 1

Related Questions