Noah
Noah

Reputation: 4751

Updating ng-repeat array

I've read many questions like this but for some reason haven't found why my code isn't working.

The goal is to have the page load with a list of items loaded by ng-repeat, which works fine, but then when the user performs a function, have that ng-repeat array replaced with another one of the same structure. It's got through http.

The code is like this.

// in HomeController

$scope.content = {
    items: [ {
        title: "hi!"
    } ]
}

$scope.search = function() {
    if ( $scope.query == '' )
        return $scope.content = null

    $http
        .get( '/api/search', { params: 
            { terms: $scope.query }
        } )
        .success( function ( results ) {
            console.log( results)
            $scope.content.items = results
        })
        .error( function ( error ) {
            $flash.error = error
        })
}

then

// in the HTML

<div ng-controller="HomeController" class="list-container">

    <div class="panel panel-item" ng-repeat="item in content.items">
        <h2 ng-bind="item.title"></h2> // ... etc

Then elsewhere there is an ng-change that triggers search(). I know the http.get works because I see it in the console. But it doesn't update the main source of ng-repeat or even the scope, from the looks of it.


Is it relevant if this controller is nested in another one?

Upvotes: 2

Views: 291

Answers (1)

Robert Koritnik
Robert Koritnik

Reputation: 105029

Solution

The problem you're having is this line:

return $scope.content = null;

Because at this point you destroy your object $scope.content which means it doesn't have any subordinate properties or anything. So when you afterwards try to assign a value to its property, that property doesn't exist on a null variable you get a runtime error:

Cannot set property 'items' of null

So if you changed upper line to

return $scope.content.items = null;

everything should work. This way your content doesn't get destroyed it just reassigns its inner property a new value.

Or you could also keep your initial line but change assignment afterwards to

$scope.content = {
    items: result
};

So when you get results you recreate the whole content object that may have been destroyed before (assigned to null).

But I would personally suggest you change upper problem code line to this:

$scope.content.items = [];
return null; // change to whatever return value seems appropriate

Which will keep your property as Array as it initially was. You'll just empty it. Sometimes it's best if you think of Javascript as a strong type language and don't execute code that would break in a strongly typed language.

Here's an example with side-by-side comparison of both working versions to the one that you're using and doesn't work.

Upvotes: 2

Related Questions