AngularJs: How make ui-select working properly?

FrancescoMussi picture FrancescoMussi · Oct 22, 2014 · Viewed 26.6k times · Source

THE SITUATION:

I am making an angular app where I have to use ui-select: in the user info page, in the select have to be possible to choose one or many tag. It is almost working, except from the fact that i have problems to get and display the pre-existent tags.

THE CODE:

View:

<ui-select multiple ng-model="info_data.tags" theme="bootstrap" ng-disabled="disabled">

  <ui-select-match placeholder="Select tag...">{{$item.name}} </ui-select-match>

  <ui-select-choices repeat="tag in all_tags | propsFilter: {name: $select.search}">

    {{tag.name}}

  </ui-select-choices>

</ui-select>

<p>Selected: {{info_data.tags}}</p>

Controller:

$http({

    url: base_url + 'main/db_get_all_tags',
    method: "POST",

 }).success(function (data) {

    $scope.all_tags = data;

});

$scope.show_info = function() {

    var result_info = DbService.get_info( $stateParams.db_data_id );

    result_info.then( function( data )
    {
        $scope.info_data = data;

    });

};

ATTEMPT 1:

It happens a very strange behavior. I don't see the tags in the info page of the user, and not even in the ui-select. Except if refresh 5/6 times, then suddenly it will magically work, displaying the tags in the user info page and in the ui-select. In both cases, working and not, i get several error message of the same kind:

Cannot read property 'length' of undefined.

ATTEMPT 2:

In order to resolve this problem, I have added this code in the controller:

$scope.info_data = { tags: [] };
$scope. all_tags = [];

And i don't get anymore any error message. The app is stable and i can see the proper tags in the user info page. The only problem is that the tags are not loaded anymore in the ui-select.

If i select a new tag then it works fine, but i loose the pre-existing tags.

QUESTION(s):

How can i make ui-select properly working? (currently v0.8.3) There is a problem of conflict?

How can i properly call pre-existent data from the server?

Thank you very much!

Answer

Nick Martin picture Nick Martin · Nov 16, 2014

You haven't been particularly descriptive with the errors you're seeing so I don't know if the following will help..

I had a problem originally when using the ui-select demo code as an example because they're using the propsFilter filter which is a custom filter they have written for the demo:

<ui-select-choices repeat="tag in all_tags | propsFilter: {name: $select.search}">

I am assuming you're not including this filter in your code which may be a reason you're experiencing a problem. You can resolve it by using angular's normal filter:

<ui-select-choices repeat="tag in all_tags | filter: {name: $select.search}">

Alternatively, if you have multiple properties to filter you can write the propsFilter filter to filter on OR rather than AND. If you use 'filter' to filter multiple properties it will try to match the search value across all of the properties.

app.filter('propsFilter', function() {
  return function(items, props) {
            var out = [];
                if (angular.isArray(items)) {
                  items.forEach(function(item) {
                        var itemMatches = false;

                        var keys = Object.keys(props);
                        for (var i = 0; i < keys.length; i++) {
                              var prop = keys[i];
                              var text = props[prop].toLowerCase();
                              if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
                                    itemMatches = true;
                                    break;
                                  }
                            }

                            if (itemMatches) {
                              out.push(item);
                            }
                      });
                } else {
                  // Let the output be the input untouched
                      out = items;
                }

                return out;
          };
    });

you can see the commit with the filter in it here: https://github.com/angular-ui/ui-select/commit/3fac88cfad0ad2369c567142eadba52bdb7998b1

Although if you have some specific filtering requirements I would recommend you to write your own filter to ensure optimum performance.