Updating a scope property doesn't update the view [duplicate] - angularjs

This question already has an answer here:
ng-show="true" but still has class="ng-hide"
(1 answer)
Closed 4 years ago.
This is a question I've seen been asked many times before but I can't seem to find a solution that works for me. I have a simple code that updates a loading property and two divs, one that's supposed to be shown when loading is true and one that's shown when loading is false.
$scope.loading = true;
function getTasks() {
$http.get(URL)
.then(function (response) {
//success
$scope.tasks = response.data;
}
, function () {
//failure
$scope.errorMessage = "Failed to fetch tasks";
$timeout(getTasks(), 5000);
})
.finally(function () {
$scope.loading = false;
});
}
The HTML is as follows:
<div ng-show="{{ loading === true }}">
<i class="fa fa-spinner fa-w-16 fa-spin fa-lg"></i>
</div>
<div ng-show="{{ loading === false }}">
However, even though loading does change to false, it doesn't update the view.
Some of the things I've tried are:
Using the timeout service
$timeout(() => {
$scope.loading = false;
});
Using $scope.$apply() both after changing loading to false and calling a function inside of apply.
Adding the getTasks function to the scope.

<div ng-show="{{ loading === true }}"> should be <div ng-show="loading === true"> or just
<div ng-show="loading">
loading is a variable defined in your scope. And you can access scope variables as it is in your angular directives ng-show in your case

Related

AngularJS ng-if does not work

In the controller, I have this
var onComplete = function(response)
{
$scope.reportList = response.data;
$log.info($scope.reportList);
};
In the HTML, reportList is a JSON like this {packageType=1, salary=12900 }.
ReportList is not an array {{ reportList.packageTypeId }} return 1
The issue is with ng-if div
<div class="exceptionProcedure" ng-if=" reportList.packageType == 1">
<a> display package 1 </a>
when I tried this, it still does not work
<div class="exceptionProcedure" ng-if=" {{reportList.packageType}} == 1">
<a> display package 1 </a>
Any ideas?
You need to define reportList.packageType on the initial page load so that it links between your controller and view:
$scope.reportList = {}
var onComplete = function(response) {
$scope.reportList = response.data;
$log.info($scope.reportList);
};
This way, you'll only have one version that is shared between controller and view. The way you're doing it now creates two separate versions.

angularjs: scope value doesn't get updated in view

there are buttons in detail.html file:
<div ng-controller="test.views.detail">
<div data-ng-repeat="item in details" scroll>
<button ng-click="showDetails(item)">The details</button>
in detail.js file
angular.module('test')
.controller('test.views.detail', function($scope) {
$scope.detailsClicked = false;
$scope.showDetails = function(item){
$scope.detailsClicked = true;
}....
in formDetail.html code:
<div ng-controller="test.views.detail">
{{detailsClicked}}
<div ng-if="detailsClicked">...
Initially it shows false for detailsClicked, when I click on button it goes to showDetails function but value of $scope.detailsClicked never get updated! It is straight forward not sure why it doesn't work:(
This is because you're using the same controller at two places and expecting the scope object to be the same which it is not. Everytime you call ng-controller in your markup a new scope object will be created. If you want them to be based off the same data then use a service.
Here is an example
app.controller('test.views.detail', function($scope, detailsClicked) {
$scope.detailsClicked = detailsClicked;
$scope.showDetails = function(item){
$scope.detailsClicked.isClicked = true;
}
});
Create a factory/service which will retain the data, make sure the data is a
app.factory('detailsClicked', function(){
var data = {
isClicked: false
}
return data;
});

How to call $scope.$apply() using "controller as" syntax

I am trying to limit my use of $scope in my controllers as much as possible and replace it with the Controller as syntax.
My current problem is that i'm not sure how to call $scope.$apply() in my controller without using $scope.
Edit: I am using TypeScript 1.4 in conjunction with angular
I have this function
setWordLists() {
this.fetchInProgress = true;
var campaignId = this.campaignFactory.currentId();
var videoId = this.videoFactory.currentId();
if (!campaignId || !videoId) {
return;
}
this.wordsToTrackFactory.doGetWordsToTrackModel(campaignId, videoId)
.then((response) => {
this.fetchInProgress = false;
this.wordList = (response) ? response.data.WordList : [];
this.notUsedWordList = (response) ? response.data.NotUsedWords : [];
});
}
being called from
$scope.$on("video-switch",() => {
this.setWordLists();
});
And it's (the arrays wordList and notUsedWordList)
is not being updated in my view:
<div class="wordListWellWrapper row" ng-repeat="words in wordTrack.wordList">
<div class="col-md-5 wordListWell form-control" ng-class="(words.IsPositive)? 'posWordWell': 'negWordWell' ">
<strong class="wordListWord">{{words.Word}}</strong>
<div class="wordListIcon">
<div class="whiteFaceIcon" ng-class="(words.IsPositive)? 'happyWhiteIcon': 'sadWhiteIcon' "></div>
</div>
</div>
<div class="col-md-2">
<span aria-hidden="true" class="glyphicon-remove glyphicon" ng-click="wordTrack.removeWord(words.Word)"></span>
</div>
</div>
Along the same lines of $apply, is there another way of calling $scope.$on using Controller as?
Thanks!
To answer the question at hand here, you can use $scope() methods in a controller when using the controller-as syntax, as long as you pass $scope as a parameter to the function. However, one of the main benefits of using the controller-as syntax is not using $scope, which creates a quandary.
As was discussed in the comments, a new question will be formulated by the poster to review the specific code requiring $scope in the first place, with some recommendations for re-structuring if possible.

How to show value on ng-click event?

I am bit new to AngularJs and looking for help on some basic concepts.
Basically the following code correctly shows data returned from request API.
Request.cshtml
<div data-ng-controller="PostsController">
<strong class="error">{{ error }}</strong>
<strong data-ng-show="loading">loading..</strong>
<div data-ng-repeat="request in posts | orderBy: 'Id':true">
<strong>ID: {{ request.Id }}</strong>
<strong>Contact No: {{ request.ContactNumber }}</strong>
</div>
</div>
now i am further looking to add button in view and when user click on in, the contact number should be displayed.
i have written following html/angular view code.
show number
I need help in writing the corresponding "ShowNumber()" function in PostsController.js file.
But i am confused how to send single value instead of lists. Any help on it please?
here is my current PostsController.js code
function PostsController($scope, $http) {
$scope.loading = true;
$scope.editMode = false;
$http.get('/api/request').success(function (data) {
$scope.posts = data;
$scope.loading = false;
})
.error(function () {
$scope.error = "An Error has occured while loading posts!";
$scope.loading = false;
});
}
The function:
$scope.ShowNumber=function(value){
//Your logic
}
HTML
<input type="button" value="Show" ng-click="ShowNumber(request.Id)" />
You can send any value in the function.
Also you can send a index of list:
ng-click="ShowNumber($index)"

Refreshing of observables in AngularJS

I'm using AngularJS and can't find way to resolve this Issue:
there is part from my controller:
$scope.$on('showMoreNotifications', function (event) {
$.ajax({
url: '/notifications',
data: {
notificationCount: 30
},
success: function (e) {
$scope.notifications = e.Messages;
}
});
});
and here is html which using this controller:
<div class="widget" id="widget-notifications" ng-controller="NotificationsCtrl">
<span class="title" ng-click="$parent.$broadcast('showMoreNotifications')">#*showMoreNotifications()*#
Notifikace
</span>
<div class="messages">
<div ng-repeat="item in notifications" class="message-item type-{{item.Entity}}" data-id="{{item.AuditLogId}}">
<span class="type"></span>
<div class="description">
<span class="date">{{item.Date}}</span> / {{item.Message}}
</div>
</div>
</div>
</div>
If I click on span class title on top, controller right call to server and receives JSON data. Unfortunately dont refresh html which is associated with it. When I click second time, html refresh data from first request.
Your template is not updating since your are making xhr calls using jQuery. Those calls are considered "outside of AngularJS" world so AngularJS is not aware of them and doesn't know that it should start it automatic refresh cycle.
You would be much better using excellent $http service from AngularJS to make xhr calls. You would write something like:
$http('/notifications', {params : {
notificationCount: 30
}}).success(function (e) {
$scope.notifications = e.Messages;
});
There was a similar question where the answer helps migrating from jQuery's $.ajax to AngularJS $http: https://stackoverflow.com/a/12131912/1418796
Next, something not directly related, but you really don't have to broadcast events to react on the click event. It would be enough to write:
<span class="title" ng-click="myClickHandler()">
#*showMoreNotifications()*#
Notifikace
</span>
and then in your controller:
$scope.myClickHandler = function(){
//call $http here
}
Now I resolved my issue... It needs apply on scope
like this:
$.ajax({
url: Escudo.UrlHelper.baseUrl + 'Widgets/Notifications/GetLastNotifications',
data: {
notificationCount: 30
},
success: function (e) {
$scope.$apply(function () {
$scope.notifications = e.Messages;
});
}
});

Resources