Skip to content
This repository has been archived by the owner on Dec 1, 2023. It is now read-only.

Typeahead promise bug in Angular 1.4.x Error: [filter:notarray] #1567

Closed
trevcor opened this issue Mar 11, 2015 · 20 comments
Closed

Typeahead promise bug in Angular 1.4.x Error: [filter:notarray] #1567

trevcor opened this issue Mar 11, 2015 · 20 comments

Comments

@trevcor
Copy link

trevcor commented Mar 11, 2015

I know that 1.4 is still in beta but I wanted to cal this out. When passing a promise to bs-options angular throws the below error:

Error: [filter:notarray] http://errors.angularjs.org/1.4.0-beta.5/filter/notarray?    p0=%7B%22%24%24state%22%3A%7B%22status%22%3A0%7D%7D
@e-oz
Copy link
Contributor

e-oz commented Mar 17, 2015

Caused by this breaking change: angular/angular.js#9992
It's only bug I have with 1.4 and I can't switch dependency...

@trevcor
Copy link
Author

trevcor commented Mar 17, 2015

That bug cites IE9. Sorry I didn't mention my browser, was using Chrome Version 41.0.2272.89 (64-bit). So did they make a fix for IE9 that caused this bug?

@e-oz
Copy link
Contributor

e-oz commented Mar 17, 2015

@trevcor sorry, I just linked wrong issue (many tabs opened).
Now fixed.
Thanks, @justincy, we love you.

@yaboi
Copy link

yaboi commented May 6, 2015

bump - having this issue too and can't switch dependencies away from Angular beta...

@mrweiland
Copy link

Is this on the road to fix - i cannot update to angular 1.4 either because of this. .:(

<input type="text" ng-model="users" typeahead-on-select="loadSelectedProfile($item)" placeholder="Sök RAQT användare"
                       typeahead="users.firstName + ' ' + users.surname for users in getAccounts($viewValue)| filter:$viewValue" typeahead-loading="loadingLocations" class="form-control">
          ```

Controller

        ```$scope.loadSelectedProfile = function (val) {
            //alert(val.id);
            $state.go('profile', { profileId: val.id });
        };

        $scope.getAccounts = function (val) {
            return $http.get('https://xxx.net/api/Account/Users/0/50', {
                method: 'get'
            }).then(function (response) {
                console.log(response.data);
                return response.data.users.map(function (item) {
                    return item;
                });
            });
        };

@capaj
Copy link
Contributor

capaj commented May 28, 2015

@mrweiland you can try my fix, but I guess it is going to take a bit more time to fix the failing tests

@Hrafnkellos
Copy link

We're having this problem as well, with Angular-Strap 2.2.2 and AngularJS 1.4.1

Line 1719 in angular-strap.js

$parseOptions.valuesFn = function(scope, controller) {
  return $q.when(valuesFn(scope, controller)).then(function(values) {
    $parseOptions.$values = values ? parseValues(values, scope) : {};
    return $parseOptions.$values;
  });
};

Then AngularJS calls $parseOptions.valuesFn and here, it crashes.

Line 18220 in angular.js

if (!isArrayLike(array)) {
  if (array == null) {
    return array;
  } else {
    throw minErr('filter')('notarray', 'Expected array but received: {0}', array);
  }
}

Here array is a Promise object, not an array. So we get the following error:

Error: [filter:notarray] Expected array but received: {}

Is this a issue in Angular-Strap or in AngularJS 1.4.x ?

@christrude
Copy link

Having this issue, sans angular-strap. Trying to use filter to search through an array set in the front end, that is being 'track by $index', but its telling me the same error as everyone else. This is holding me back from updating.

Error: [filter:notarray] Expected array but received: 0

@mgcrea mgcrea closed this as completed in 98c3919 Jul 12, 2015
mgcrea added a commit that referenced this issue Jul 14, 2015
@spamforhope
Copy link

My fix is working.
Set data array in your controller like $scope.dataArr;

in promise set data to this array. On your input with typeahead set ng-change="$scope.promiseFunc()" and typeahead="obj for object in dataArr | filter:$viewValue "

@HarelM
Copy link

HarelM commented Aug 13, 2015

How do I pass current input value to the promiseFunc?
Is it possible to update the documentation with this workaround? I'm experiencing the same issue.
Does this workaround works with minLength?

@spamforhope
Copy link

$scope.promiseFunc($viewValue)

@HarelM
Copy link

HarelM commented Aug 14, 2015

tried that, viewValue is undefined. I ended up using the variable in ng-model. But this workaround shows search results only a character after user input which is not so great... Can this issue be reopen? The try catch does not really fix this...

@HarelM
Copy link

HarelM commented Aug 15, 2015

Never mind, Updated to latest angular (1.4.3) and angularstarp solved my issue.

@blanchma
Copy link

@HarelM what did you do to fix this besides updating to 1.4.3 and installing angularstrap?

@HarelM
Copy link

HarelM commented Sep 14, 2015

That was it, but I ended up not using it since I needed to show search results and allow the user to select and pan my map.

@blanchma
Copy link

@HarelM so you couldn't fix this problem neither. Did you create your own typeahead?

@HarelM
Copy link

HarelM commented Sep 14, 2015

Here is my site:
http://osm.org.il/IsraelHiking/IsraelHikingMap.html
On the right side you can see a search icon. This search is using "Nominatim" to get the location of geographic places. When a user uses this search the search results are presented not exactly are they come from the Nominatim server and therefore I couldn't use typeahead in this case. I did manage to make it work after version upgrade but the problem with the results name manipulation made me write my own search adapter...

@JuanHB
Copy link

JuanHB commented Sep 23, 2015

@HarelM I was with the same issue with the filter logic in the typeahead repeat, I was doing this:

typeahead="user for user in vm.getUsers($viewValue) | filter{name:$viewValue}"

... and the was getting the error message from angular saying he can't handle objects in the filter.

After some debugging I saw that by making this:

...
return users.getByName(name)
         .then(function(result){
             return result.data.map(function(user){
                 // "user" is a object full of user information, 
                 // like his avatar, id, name, email, etc...
                 return user;
             });
         });
...

I was, in fact, transforming my returned array of users in an Object and AngularJS was correct when he was throwing me errors...

Ok, so I tried @spamforhope suggestion, It worked, but not with the results I wanted and then I returned to the main example here: http://angular-ui.github.io/bootstrap/#/typeahead

I paid real attention to the examples there and noticed the third example, "Custom templates for results" and tried what it suggests:

typeahead="user as user.name for user in vm.getUsers($viewValue)"
...

... and worked like a charm!

The difference between the two loop logics? In the second I'm using the as syntax for my loop, so when the user selects someone in the list, the $viewValue still contains the Object but inside the typeahead template, the match.label node is the username.

Edit:
AngularJS: v1.4.6
UI Bootstrap: v0.13.4

@lukaszpaczos
Copy link

I have the same issue, so i change in version 2.3.6 in angular-strap.js on line 711:

  } else {
    return $filter('filter')(array, expression, comparator);
  }

to:

  } else {
    if (typeof array !== 'array') {
      array = [];
    }
    return $filter('filter')(array, expression, comparator);
  }

I use angular 1.4.7

@lock
Copy link

lock bot commented Jan 26, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot added the outdated label Jan 26, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Jan 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.