AngularJs asynchronous data binding - angularjs

I'm very new to AngularJs and I have simple question. I want to put the name. But this name has one value at first but after 0.3-0.5 sec it have other value. I don't know how to bind it, that the value could change.
HTML code:
<div ng-controller="FormController">
<h2 >
{{getName()}}<br>
<span class="icon-f-gear"></span>
<small>Procesas</small>
</h2>
</div>
Angular controller:
var App = angular.module('form', ['ui.bootstrap']);
App.controller('FormController', ['$scope' ,'$http', function($scope, $http) {
$scope.tasks = [];
$scope.socket.stomp.subscribe("/app/tasks", function (message) {
if ($scope.tasks.length !=0){
$scope.tasks.removeAll();
}
JSON.parse(message.body).forEach(function (el) {
$scope.tasks.push(el);
});
});
$scope.getName = function(){
return $scope.tasks[0].form.name;
};
I'm using Stomp protocol, it gives me data not instantly, because it has to send request to server and get it back, it takes time. I tried to debug after the request variable $scope.tasks[0].form.name changes from undefined to "Institution", but in the screen undefined stays, how to bind variable to change the value dinamically. Thanks for help in advance!
UPDATE
Problem solved, I just had to use $scope.apply(...) function. Code here:
var App = angular.module('form', ['ui.bootstrap']);
App.controller('FormController', ['$scope' ,'$http', function($scope, $http) {
$scope.tasks = [];
$scope.socket.stomp.subscribe("/app/tasks", function (message) {
if ($scope.tasks.length !=0){
$scope.tasks.removeAll();
}
JSON.parse(message.body).forEach(function (el) {
$scope.tasks.push(el);
});
$scope.apply(function(){$scope.tasks});
});
$scope.getName = function(){
return $scope.tasks[0].form.name;
};
Thanks for help!

Most probably the subscribe callback is not being called in angular context. Try to wrap the callback code in $scope.$apply and see if it works
$scope.socket.stomp.subscribe("/app/tasks", function (message) {
$scope.$apply(function() {
if ($scope.tasks.length !=0){
$scope.tasks.removeAll();
}
JSON.parse(message.body).forEach(function (el) {
$scope.tasks.push(el);
});
});
});

I believe the method you are calling returns undefined, because it has no data.
In other words: give it an initial value, and it should work
I would rewrite it to:
<div ng-controller="FormController">
<h2>
{{formName}}<br>
<span class="icon-f-gear"></span>
<small>Procesas</small>
</h2>
</div>
And
App.controller('FormController', ['$scope' ,'$http', function($scope, $http) {
$scope.formName = '';
--- rest of code
Or, if you wish to keep it in the current way:
App.controller('FormController', ['$scope' ,'$http', function($scope, $http) {
$scope.tasks = [];
$scope.tasks[0].form.name = '';
or
$scope.getName = function(){
return ($scope.tasks.length > 0) ? $scope.tasks[0].form.name : '';
};
I hope this helps

Related

How to call a method from a controller to another controller in angular js

I have a view for SidebarController like below -
<a ng-click="reachMe($event);$event.preventDefault()" ng-href="#/app/hello">
Before going to the link I want to call reachMe() to check some changes on page and need to show an alert if any changes made
function SidebarController($rootScope, $scope, $state, $location, SidebarLoader){
$scope.reachMe = function(event){
//here I want to call function isPageChanged() from StaticPageController
//something like this
// if StaticPageController.isPageChanged() return true
// then show alert
// else
// $location.url($href)
}
}
Update 1 :
Not sure about this, But give it a try.
<div ng-app="testApp" ng-controller="ControllerOne">
<button ng-click="methodA();"> Call Another Controller</button>
</div>
<script>
var app = angular.module('testApp', []);
app.controller('ControllerOne', function($scope, $rootScope) {
$scope.reachMe = function() {
var arrayData = [1,2,3];
$rootScope.$emit('callEvent', arrayData);
if($rootScope.isChanged){
// Show Alert
}else{
//Go to route
}
}
});
app.controller('ControllerTwo', function($scope, $rootScope,$state) {
$scope.checkSomethingChanged = function() {
alert("Hello");
$rootScope.isChanged = true;
}
$rootScope.$on('callEvent', function(event, data) {
console.log(data);
$scope.checkSomethingChanged();
});
});
Following method worked for me perfectly :
<div ng-app="testApp" ng-controller="ControllerOne">
<button ng-click="methodA();"> Call Another Controller</button>
</div>
<script>
var app = angular.module('testApp', []);
app.controller('ControllerOne', function($scope, $rootScope) {
$scope.methodA = function() {
var arrayData = [1,2,3];
$rootScope.$emit('callEvent', arrayData);
}
});
app.controller('ControllerTwo', function($scope, $rootScope) {
$scope.reachMe = function() {
alert("Hello");
}
$rootScope.$on('callEvent', function(event, data) {
console.log(data);
$scope.reachMe();
});
});
</script>
A controller is not the right concept for sharing functionality. Use a Factory or Service for that.
var logicFactory = function () {
return {
methodA: function () {
},
methodB: function()
{
}
};
}
You can then inject that factory into each controller where it is needed like:
var ControllerA = function ($scope,logicFactory) {
$scope.logic = logicFactory;
}
ControllerA.$inject = ['$scope', 'logicFactory'];
Another option is to use the broadcast/emit Patern. But I would use that only where really necessary:
Usage of $broadcast(), $emit() And $on() in AngularJS

AngularJS- How to pass data from one controller to another on ng-click()?

So I am trying to share data between two controllers on an on-click event. My code is as follows:
Controller
function userTypeController($scope, $location, CategoryService) {
let vm=this;
vm.getCat=function(){
CategoryService.getCategories() .then(function (response)
{
$scope.categories=response.data.data.categories;
$scope.index = 0;
$scope.array = [];
for(var i=0; i<$scope.categories.length/2;i++)
$scope.array.push(i);
});
$location.path('/category');
};
};
Say in my html for that controller, I have a button that calls the getCat function.
<md-button md-whiteframe="8" ng-click="utCtrl.getCat()">Submit<md-button>
In my category service , I have a function that returns a list of categories.
Service
return {
getCategories: function () {
return $http.get(url2);
}
Now i want the array of categories that I get from the server to be accessible in my Categories controller. I was using $rootScope before to share the date from usertype controller to the other one but its not the ideal thing to do. I want $scope.array to be accessible in my categories controller so i can display that in its view. What would be the best way to do this. Thanks a lot!
You should consider using a service in this case to share the data across your controllers.
SharedService.js
app.service('sharedService', function(){
var categories = [];
names.add = function(incategories){
categories = incategories;
};
names.get = function(){
return categories;
};
});
then inject in your controller1 and controller2 and use depending on your requirement.
app.controller("TestCtrl",
function($scope,sharedService) {
$scope.categories =[];
$scope.save= function(){
sharedService.add(yourcat);
}
}
);
and then use it as,
app.controller("TestCtrl2",
function($scope,sharedService) {
$scope.getcategories = function(){
$scope.categories = sharedService.get();
}
}
);
This will get you results instantly, No need of service or anything,You can use $broadcast for multiple controllers as well :
<div ng-app="myApp" ng-controller="myCtrl">
<button ng-click="sendData();"></button>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($rootScope, $http) {
function sendData() {
var arrayData = [1,2,3];
$rootScope.$emit('eventName', arrayData);
}
});
app.controller('yourCtrl', function($rootScope, $http) {
$rootScope.$on('eventName', function(event, data) {
console.log(data);
});
});
</script>

angularjs: not able to pass a variable value from controller to view

(function() {
angular
.module('myApp.home', [])
.factory('myService', function($http) {
return {
getInfo: function() {
// return something
}
};
})
.controller('HomeController', function($scope, $routeParams, myService) {
var my = this;
var sid;
myService.getInfo().success(function(data) {
my.id = data.id;
//sid= my.id;
});
//my.id = sid;
});
})();
I'm trying to access the variable id in my view. But I'm not able to do so. I'm getting an undefined variable error.
I even tried to declare a variable sid globally so that it can be accessed from everywhere and I tried assigning value to it as well but that effort also didn't bring up any results.
My services are working fine and they are returning data. I'm trying to use the id in my view but don't know where I messed it up.
Any help?
EDIT
And my HTML is like this:
<div data-id="my.id"></div>
If you want to use it in your view you have to bind it to a scope e.g. $scope.id - check this link for reference.
Below is your html, how it should be.
<div ng-app="app" ng-controller="HomeController as home">
<div data-id="home.id">{{home.id}}</div>
</div>
Below is how your controller part.
angular.module('app', [])
.controller('HomeController', function () {
this.id = "someValue";
});
http://jsfiddle.net/grdmLfxt/
use controllerAs : vm then you can access vm.id in your view.
HTML
<div ng-app="app" ng-controller="HomeController as vm">
<div data-id="vm.id">{{vm.id}}</div>
</div>
Controller
.controller('HomeController', function () {
var vm = this;
vm.id = "someValue";
});
for more info read this
small change in javascript code and html. try this.
Javascript
(function() {
angular
.module('myApp.home', [])
.factory('myService', function($http) {
return {
getInfo: function() {
// return something
}
};
})
.controller('HomeController', function($scope, $routeParams, myService) {
var my = this;
var sid;
myService.getInfo().success(function(data) {
$scope.id = data.id; // changed from my.id to $scope.id
//sid= my.id;
});
//my.id = sid;
});
})();
HTML
<div data-id="id"></div>

Passing Data Between Controllers - Frustrated by lack of clarity in other answers

Like many before I want to pass data between controllers. Specifically I want the user to be able to keep track of creating another user. I looked at the following SO explanations and came away not getting the results I was looking for or with answers that I don't know how to implement:
How can I pass some data from one controller to another peer controller
angularjs - passing data between controllers
AngularJS: How can I pass variables between controllers?
I also don't think broadcast is the solution to the problem. I think this is something that should be done with a service or factory (either will do as long as it works since I don't really understand the difference between them right now)
My code:
SERVICE
angular.module('startupApp')
.service('vendorId', function () {
// AngularJS will instantiate a singleton by calling "new" on this function
var VendorId = [];
var Vendor = [];
return {
setVendorId: function(vendorId){
VendorId.push(vendorId);
},
getVendorId: function(){
return VendorId;
},
setVendor: function(vendor){
Vendor.push(vendor);
},
getVendor: function(){
return Vendor;
}
};
});
CONTROLLER 1
angular.module('startupApp')
.controller('controller1', function ($scope, Auth, $location, vendorId, $http) {
$scope.user = {};
vendorId.setVendor($scope.user);
vendorId.setVendorId($scope.user.id);
})
CONTROLLER 2
angular.module('startupApp')
.controller('controller2', function ($scope, Auth, $location, vendorId, $http) {
console.log(vendorId.getVendor());//[]
console.log(vendorId.getVendorId());//[]
})
These both end up as empty arrays. To be clear, there is page1.html that has a form that populates the $scope.user object in controller1. I want to be able to get this object on page2.html from the page2.html controller (controller2)
Your code should work, unless controller1 is not invoked before controller2.
run this code snippet and see by yourself.
angular.module("test", [])
.service("vendorId", function () {
var VendorId = [];
var Vendor = [];
return {
setVendorId: function(vendorId){
VendorId.push(vendorId);
},
getVendorId: function(){
return VendorId;
},
setVendor: function(vendor){
Vendor.push(vendor);
},
getVendor: function(){
return Vendor;
}
};
})
.controller("Controller1", function ($rootScope, vendorId) {
this.user = {id : 1};
this.save = function () {
vendorId.setVendor(this.user);
vendorId.setVendorId(this.user.id);
// simulates page change
$rootScope.saved = true;
}
})
.controller("Controller2", function (vendorId) {
this.user = vendorId.getVendor();
this.id = vendorId.getVendorId();
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-app="test">
<div data-ng-if="!saved" data-ng-controller="Controller1 as scope1">
<input type="text" data-ng-model="scope1.user.name" />
<button data-ng-click="scope1.save()">Save</button>
</div>
<div data-ng-if="saved" data-ng-controller="Controller2 as scope2">
The user : {{scope2.user}} <br />
The user id : {{scope2.id}}
</div>
</div>

How to access a variable in a controller function?

I'd like to be able to access a controller variable inside a function of this controller.
Why is the following code throwing an error into the console instead of showing the input value ?
JS:
var app = angular.module("app", []);
app.controller("TestCtrl", function($scope) {
$scope.string = "";
$scope.click = function() { // I've also tried with $scope in parameter
console.debug(string); // and $scope.string here, same issue
}
});
HTML :
<div ng-app="app" ng-controller="TestCtrl">
<input type="text" ng-model="string"></input>
<button ng-click="click()">Click me !</button>
</div>
JSFiddle
remove $scope from the argument in you click function, and use it inside the function - see below and updated fiddle
app.controller("TestCtrl", function($scope) {
$scope.string = "";
$scope.click = function() {
console.debug($scope.string);
}
});
You can try another approach:
app.controller("TestCtrl", function($scope) {
this.string = "";
var that = this;
$scope.click = function() {
console.debug(that.string);
}
});
See on JSFiddle:
http://jsfiddle.net/qn47syd2/

Resources