I have a main controller and nested controllers within it. In the main controller I have defined object by async query to the service, and try to use the object in the nested controller. But in the object in the nested controller is empty, cause it fires before it will be updated in the main controller.
As I understand, asyncronous query should updates the scope after data obtain?
.controller('MainController', ['$scope', function($scope) {
$scope.uData = {};
$scope.uDataCurrent = {};
$scope.usersData = usersFactory.getUsersData().query(
function(response) {
$scope.uData = response;
$scope.uDataCurrent = $filter('filter')($scope.uData, {'user':$scope.myuser});
$scope.uDataCurrent = $scope.uDataCurrent[0];
},
function(response) {
$scope.message = "Error: "+response.status + " " + response.statusText;
});
})]
.controller('NestedController', ['$scope', function($scope) {
console.log($scope.uDataCurrent); // returns empty object
}])
Service:
.service('usersFactory', ['$resource', 'baseURL', function($resource,baseURL) {
this.getUsersData = function(){
return $resource(baseURL+"/index.php?app=users&format=raw&resource=user",null, {'update':{method:'PUT' }});
};
}])
You could use $scope.$watch.
angular.module("App", [])
.controller("OuterCtrl", ["$scope", "$timeout", function($scope, $timeout) {
$scope.users = null;
$timeout(function() {
$scope.users = ["John", "Jack"];
}, 500);
}]).controller("InnerCtrl", ["$scope", function($scope) {
$scope.changeCount = 0;
// TODO: Bad practice to rely on outer scopes here as its not enforced
// to have an OuterCtrl scope as parent scope. In this example every
// occurrences of InnerCtrl is embedded in an OuterCtrl in the html
$scope.$watch("users", function(newValue, oldValue) {
// This code runs when the users array is changed
$scope.changeCount++;
});
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.js"></script>
<div ng-app="App">
<div ng-controller="OuterCtrl">
<div ng-controller="InnerCtrl">
<div>Change count: {{changeCount}}</div>
<div>Users</div>
<div ng-hide="users"> Loading...</div>
<ul>
<li ng-repeat="name in users">{{name}}</li>
</ul>
</div>
</div>
</div>
Related
i have a html like below
<a class="event_detail_btn_a" ng-click="foo()"></a>
following is my controller
onsenApp.controller("EventDetailController", function ($scope) {
$scope.foo = function(){
alert("foo!");
var options = {
data: {
title: 'Another Page'
}
};
};
});
i want to pass "options" variable to another controller from this controller.
how can i do it ?
Use $broadcast to pass data between controllers.
In the example add() is defined in Controller1 which is passed to Controller2 after 2 secs.
angular
.module("app", [])
.controller("Controller1", function($scope, $rootScope, $timeout){
var add = function(a, b) {
return a + b;
}
$timeout(function(){
$rootScope.$broadcast("Add function", add);
}, 2000);
})
.controller("Controller2", function($scope, $rootScope, $timeout){
$scope.$on("Add function", function(event, add) {
$scope.sum = add(3, 4);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="Controller1">
<span>Add function defined in Controller1</span><br /><br />
</div>
<div ng-controller="Controller2">
<span ng-show="sum">3 + 4 = {{ sum }}</span>
<span ng-show="!sum">Controller2 waiting for add function...</span><br />
</div>
</div>
Best way to create a service OR a factory and inject in both controllers like below:
var myApp = angular.module('myApp', []);
myApp.factory('MyService', function() {
var options = {
data: {
title: 'Another Page'
}
};
return {
options
};
});
myApp.controller('FirstCtrl', function($scope, MyService) {
$scope.options = MyService.options;
});
myApp.controller('SecondCtrl', function($scope, MyService) {
$scope.options = MyService.options;
});
You want to pass data to another controller, the way i am getting it is :
onsenApp.controller("EventDetailController", function ($scope) {
$scope.foo = function(){
alert("foo!");
var options = {
data: {
title: 'Another Page'
}
};
this is one way you can achieve this using event push-page with it you send data.
myNavigator.pushPage('xyz.html',
{myData: options} );
}
};
});
onsenApp.controller("SecondController", function ($scope) {
here you can get your desired data
$scope.options = myNavigator.getCurrentPage().options.myData;
});
(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>
How to fetch the scope value from one controller to another controller
html
<button class="btn btn-info" ng-click="setLanguage('en')">English</button>
<button class="btn btn-info" ng-click="setLanguage('de')">Danish</button>
Javascript
.controller('demoCtrl', function($scope) {
$scope.setLanguage = function(language) {
$scope.language = language;
}
});
You can use a service to get the value set by one controller into another controller.
.service('someService', function () {
this.language = null;
})
Controller
.controller('demoCtrl', function($scope, $rootScope, someService) {
$scope.setLanguage = function(language) {
$scope.language = language;
someService.language = language;
$rootScope.$broadcast('languageChanged');
}
});
In the other controller
.controller('someCtrl', function($scope, $rootScope, someService) {
$rootScope.$on('languageChanged', function () {
$scope.language = someService.language;
}
});
You can share data between controllers with the help of either a service or you can use $emit() and $broadcast() functions.
There is a listener function in AngularJS $on() which will always be listening to the broadcast and emit events.
The syntax for the above function :
$scope.$emit(‘name1’,{}); //here you can send your data
$scope.$broadcast(‘name2’,{});
$scope.$on(‘name2’,function(event,args){
});
When using a service you can simply inject the service into your two controllers and share the data.
.service('someService', function () {
var self=this;
self.language = '';
});
.controller('firstCtrl', function($scope, someService) {
$scope.setLanguage = function(language) {
$scope.language = language;
someService.language = language;
}
});
.controller('secondCtrl', function($scope, someService) {
$scope.language = someService.language;
});
If we want to call example method of:
"test1 DIV controller"
from:
"test2 DIV controller"
then we can write above method.
angular.Element(document.getelementByID('testDIV')).scope().example method name();
in test2DIVcontroller.
For Example :
<DIV ID="test1DIV" ng-controller="test1DIV controller"></DIV>
<DIV ID="test2DIV" ng-controller="test2DIV controller"></DIV>
I have an AngularJS Factory that is an upload, I'm trying to make the progress fire a function called progressState but it's not working.
Is there anyway of getting this to work?
myApp.factory('fooFactory', function() {
return {
upload: function(foo){
upload(foo)
.progress(evt){
progressState(evt, state);
}
},
progressState: function(evt, state){
return fooVar;
}
};
});
use this
outside return
var self = this;
inside return
self.progressState(evt, state);
I have mocked up the best I can without access to your upload function, does this help
var myApp = angular.module('myApp', []);
myApp.factory('fooFactory', function() {
var factory = {};
factory.upload = function(foo){
console.log ('factory : ' , factory)
factory.progressState();
}
factory.progressState = function(){
console.log('progress state called')
}
return factory;
});
myApp.controller('myCtrl', ['$scope', 'fooFactory', function($scope, fooFactory){
$scope.test = 'controller active';
fooFactory.upload();
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<p>{{test}}</p>
</div>
</div>
var myApp = angular.module('myApp', []);
myApp.factory('Data', function() {
return {message: "I'm data from a service"}
})
function FirstCtrl($scope, Data){
$scope.data = Data;
}
function SecondCtrl($scope, Data){
//I want to send a string to the service so that the view associated with FirstCtrl is updated.
}
Ok, lets take this code for example. How would one set the message string from inside SecondCtrl so that the view binded with FirstCtrl is updated?
You may share data between controllers using a service (factory), but you will not use $scope directly.
Please refer to this video for a demonstration:
https://egghead.io/lessons/angularjs-sharing-data-between-controllers
Thumbs up for egghead \o/
Edit:
var myApp = angular.module('myApp', []);
myApp.factory('Data', function() {
return {message: "I'm data from a service"}
})
function FirstCtrl($scope, Data){
$scope.data = Data;
}
function SecondCtrl($scope, Data){
$scope.data = Data;
// Simply set the message or bind it to an input on your view:
$scope.data.message = 'new value'
}
Here is a demo: http://jsfiddle.net/suhvtr5r/
If this doesn´t work, please share your views with us
One thing you can do is to create another parent controller like this,and put common things to both controllers
<div ng-controller="parentController">
<div ng-Controller="pageOneController">
<input placeholder="{{placeholder}}" type="text" />
</div>
<div ng-Controller="pageTwoController">
<--other html-->
</div>
</div>
app.controller('parentController', ['$scope', function($scope) {
$scope.placeholder = "this is common to both child controllers";
}]);
If you want to do that you need getter and setter in your service here is the fiddle that do the trick for you :
HTML:
<div ng-app="myApp">
<div ng-controller="FirstCtrl">my first cotroller : {{data.message}}</div>
<div ng-controller="SecondCtrl">my second controller :
<input type="text" ng-model="data.message" ng-change="update()">
</div>
</div>
Angular:
var myApp = angular.module('myApp', []);
myApp.factory('Data', function () {
return {
message: '',
get: function () {
alert("DasdaS");
return this.message;
},
set: function (secondCtrlStr) {
this.message = secondCtrlStr;
}
};
})
function FirstCtrl($scope, Data) {
$scope.data = Data;
}
function SecondCtrl($scope, Data) {
$scope.update = function () {
Data.set($scope.data.message);
};
}