Reputation: 4751
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
Reputation: 105029
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