Pass variables into AngularJS App - javascript

I am connecting to an API through a script (init.js) when starting my angular app. I then receive som information such as a username and a user ID that I want to define as global values to use in the AngularJS App.
How do I pass the variables on to use in the AngularJS app?
My thought now is to define the variables in the MainController to be able to use them anywhere.
init.js
(function () {
function appStart() {
//Get variables
var userId = 123;
var username = 'This is my name';
//Init Angular App
angular.bootstrap(document, ['myApp']); //How do I use the variables in the angular app?
}
function genericError() {
console.error('Something went wrong');
}
TT.native.init()
.done(appStart)
.fail(genericError);
})();
app.js
(function () { //Start
var app = angular.module('myApp', [
'myControllers',
'myDirectives',
'myFilters',
'myServices',
'ui.router'
]);
controller.js
var app = angular.module('myControllers', []);
app.controller('MainController', function ($scope, $state) {
$scope.userName = ""; //I want to use the variable from INIT.JS here
$scope.userId = 0; //I want to use the variable from INIT.JS here
});

The easiest solution would be:
var userId = -1;
var username = '';
(function () {
function appStart() {
//Get variables
userId = 123;
username = 'This is my name';
//Init Angular App
angular.bootstrap(document, ['myApp']); //How do I use the variables in the angular app?
}
function genericError() {
console.error('Something went wrong');
}
TT.native.init()
.done(appStart)
.fail(genericError);
})();
Then in the controller:
app.controller('MainController', function ($scope, $state) {
$scope.userName = userId;
$scope.userId = username;
});
But just know that this is not a good approach. You should connect to your api within the angular app. Maybe you should watch and read some tutorials before beginning to code...

You can use angular.module('myApp').value or angular.module('myApp').constant before bootstrapping angular. In your controller you should add variables into dependencies.

You probably using ngRouter or uiRouter so you could resolve the TT.native.init before entering the first route/state.

Related

use variable of another controller angularJS with ionic

I want to access variable from another controller any body help
My code
app.controller('MapCtrl',function($scope, $state, $cordovaGeolocation) {
$scope.search_item = function($event,item){
console.log(item);
var lat = item.lat;
var lng = item.lng;
}
});
to
app.controller("homeCtrl", function($scope,$http, $filter ){
});
You can set up a service that 'shares' the variable between the two controllers.
Create a file: services.js in the app/ directory (where app.js is located)
angular.module('app.services', [])
.service('var_transfer_service', function(){
var test_var;
return {
getVar: function () {
return test_var;
},
setVar: function( _test_var ) {
test_var = _test_var;
}
}
})
Now inject this service into the controllers that need variable sharing:
app.controller('MapCtrl',function($scope, $state, $cordovaGeolocation, var_transfer_service) {
$scope.search_item = function($event,item){
console.log(item);
var lat = item.lat;
var lng = item.lng;
var_transfer_service.setVar(lat);
}
});
app.controller("homeCtrl", function($scope,$http, $filter, var_transfer_service ){
var transferred_var = var_transfer_service.getVar();
// transferred_var will now equal 'lat' from the other controller
});
You can further modify the function definitions in services.js and function calls in your controllers to accommodate more variables.
Make sure to also add the services.js module to your app:
angular.module('app', ['ionic', 'app.controllers', 'app.services'])

Can't access $rootScope from another controller

Why can't I access the $rootScope, particulary the currentUser object and the signedIn() function from the RegistrationController?
I'm trying to follow a tutorial example and I'm able to sucessfully set the $rootScope.currentUser variable in a service (Authentication), but when I try to access it from another controller (RegistrationController) I cannot access it.
My understanding is that $rootScope is kind of a global variable that is accessible from all the app, is this correct?
myApp.controller('RegistrationController',
function($scope, $firebaseAuth, $location, Authentication, $rootScope){
$scope.login = function() {
Authentication.login($scope.user)
.then(function(userReturned){
console.log('registration.js: logged in user '+userReturned.uid);
//console.log('registration.js: $rootScope.currentUser ahora es... ');
//console.log($rootScope.currentUser);
$location.path('/meetings');
})
.catch(function(error) {
$scope.message = error.toString();
});
} //login
}); //RegistrationController
myApp.factory('Authentication',
function($firebase, $firebaseAuth, FIREBASE_URL, $location, $rootScope) {
// using $firebaseAuth instead of SimpleLogin
var ref = new Firebase(FIREBASE_URL);
var authObj = $firebaseAuth(ref);
var myObject = {
login : function(user) {
return authObj.$authWithPassword({
email: user.email,
password: user.password
})
.then(function(authData){
console.log('authentication.js: logged in user '+ authData.uid);
var userRef = new Firebase(FIREBASE_URL + 'users/' + authData.uid);
var userObj = $firebase(userRef).$asObject();
userObj.$loaded().then(function() {
$rootScope.currentUser = userObj;
});
$rootScope.$broadcast('$firebaseAuth:authWithPassword',authData); // avisa al scope
return authData;
});
}, //login
signedIn: function() {
//console.log(authObj);
//console.log('authentication.js: signedIn function called and returned '+ (authObj.user != null) );
return authObj.user != null;
} // signedIn
} //myObject
// add signedIn to the $rootScope
$rootScope.signedIn = function() {
return myObject.signedIn();
}
return myObject;
});
I believe what's happening is the promise Authentication.login is being resolved before currentUser being set $rootScope.currentUser = userObj;
to make sure this is the case, try put a breakpoint on this line in your Authentication service:
$rootScope.currentUser = userObj;
and another breakpoint on this one in your controller:
console.log($rootScope.currentUser);
and see which one is being executed before the other.
IF this is the case, try this:
Move the block of code in [THEN] statement from your service to your controller, where you are treating the current user and logging it.
It looks like you're trying to print $rootScope.currentUser from RegistrationController.login(). But currentUser was never set on $rootScope. Here's an example that demonstrates using $rootScope on two controllers.
angular.module('Main', [])
.controller("SetCtrl", function($scope, $rootScope) {
$scope.name = 'abc';
$rootScope.copy = $scope.name;
})
.controller("GetCtrl", function($scope, $rootScope) {
$scope.fromSetCtrl = $rootScope.copy;
});
http://plnkr.co/edit/dj6Y9hIEJ3KA9yAjuQP5
I'm not exactly sure how your are using your service/factory and how your apps and controllers are set up.
I think $rootScope is the "top" scope of the outermost controller of your app. You can have a $rootScope for each of your "app".
I would guess that if you set a variable in the $rootScope in the service in one of your app and then try to access your service from the $rootScope from the controller from ANOTHER app, you will not be able to find the variable because it is in another $rootScope. In that sense $rootScope is NOT a global variable.
You can access $rootScope variables directly from the child controllers if you pass in "$rootScope" when you define your controller, or from indirectly from $scope of the child controllers, because angular will look for the variable from the current controller's scope all the way up to that controller's $rootScope.
Hope this helps.

How to get service instance from module instance [Angular]

i have some module defined and services too with that module like below
var services=angular.module('app.services', []);
services.factory('ApiService', function($http,$cookies,UserService){
var dataFactory = {};
dataFactory.request=function(url,data,next){
return "Hi";
};
return dataFactory;
});
now in another script i can access module like
services=angular.module('app.services')
but how can i get service instance from that module like
apiService=angular.module('app.services').service('ApiService')
Edit:
after reading and understanding the author's comments, he was actually meant to block the entire app if the user is not permitted. his desired to do it by reusing the same code written in his ApiService factory.
--
You can 'hook' to app.run function which called before your controllers and you can utilize $window.location.href to relocate user to another page or site (if not permitted)
Iv'e updated this plunker with app.run entry
app.js
var app = angular.module('app', ['app.services']);
app.run(function(ApiService, $window) {
result = ApiService.request();
// This is where you check your permissions
var has_permissions = false;
// ...
if (!has_permissions) {
alert('being transferred to plnkr.co due to lack of permissions');
$window.location.href = 'http://plnkr.co/';
}
// Otherwise, continue normally
});
Original:
i made this plunker
if you separate all logic to api.services module, include it in your app
app.js
var app = angular.module('app', ['app.services']);
then you could use it by referencing the desired factory - ApiService
app.controller('myCtrl', ['$scope', 'ApiService',
function($scope, ApiService) {
$scope.result = ApiService.request();
}
]);
app.services.js
var services = angular.module('app.services', []);
services.factory('UserService', function() {
var UserService = {};
UserService.foo = function() {
return "foo";
};
return UserService;
});
services.factory('ApiService', function($http, UserService) {
var ApiService = {};
ApiService.request = function(url, data, next) {
return UserService.foo() + " Hi";
};
return ApiService;
});
plunker

How to implement a controller trait in AngularJS

I want to give a set of controllers access to methods and properties defined in a trait. Right now the best implementation I have come up with is:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, CtrlTrait) {
$scope.name = CtrlTrait.presetName;
CtrlTrait.setGreeting.call($scope, 'Hello');
});
app.service('CtrlTrait', function() {
this.setGreeting = function(greeting) { this.greeting = greeting; }
this.presetName = 'tom';
});
Plunkr Code
This is fine, but I would like the properties and method to be accessible via the controller's $scope without having to manually create the alias in each controller. I want to be able to use the properties and method from the template just by having injected the service into the controller.
Is this possible, or do I have to create a [wrapper around]/[provider for] $scope like $specialCtrlScope that presets the properties and methods I want?
You can try using angular.extend like this: angular.extend($scope,CtrlTrait); It will allows us to use in the $scope the same functions that your service. So, you can use the function directly in your html like this:
<button ng-click="setGreeting('Good bye! ')">Good Bye</button>
Here is your plunker demo adapted:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, CtrlTrait) {
$scope.name = CtrlTrait.presetName;
// CtrlTrait.setGreeting.call($scope, 'Hello');
angular.extend($scope,CtrlTrait);
$scope.setGreeting('Hello World');
});
app.service('CtrlTrait', function() {
this.setGreeting = function(greeting) { this.greeting = greeting; }
this.presetName = 'tom';
});
http://plnkr.co/edit/BENS78mjFfpc6VCEtgK8?p=preview
You Can try the below in your controller
$scope.setGreeting = CtrlTrait.setGreeting
and can later use
$scope.setGreeting.call($scope, 'Hello');
EDIT AFTER THE COMMENT
Try this
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, CtrlTrait) {
$scope.trait = CtrlTrait;
$scope.name = $scope.trait.presetName;
$scope.trait.setGreeting.call($scope,'Hello');
});
app.service('CtrlTrait', function() {
var trait = {};
trait.setGreeting = function(greeting) { this.greeting = greeting; }
trait.presetName = 'tom';
return trait;
});
So I'll preface this with a disclaimer... I would not recommend that you actually do this, or at least not do it in this way. You're adding extra coupling between your controllers and services inside of a framework built around modularity and injection, all for the sake of saving a few method calls.
That said, here's a way to implement what you want. (JSFiddle here)
var app = angular.module('myApp', []);
var controllerMaker = function(trait,controllerCode){
return function($scope, $injector){
//'apply' traits to this scope
var apply = function(trait){
trait.applyTo($scope);
}
apply.$inject = [trait];
$injector.invoke(apply);
//Finishes the other injections
controllerCode.$inject = ['$scope'];
controllerCode($scope);
};
}
//Here's a sample 'trait'
app.service('CtrlTrait', function() {
this.applyTo = function(obj){
obj.setGreeting = function(greeting) { this.greeting = greeting; }
obj.presetName = 'tom';
}
});
//Then, setup your controller like this
app.controller('GreatController', controllerMaker("CtrlTrait",function($scope){ //Not using injection though!
$scope.bleh = $scope.presetName; //will be 'tom'
}))
There are certainly weaknesses with this, like how your controller loses injection, but if you reeeeeeally wanted to, I'm sure you could play aruond with $inject and find something that suits your needs.
Angular will inject the return value of a the function if it is an object. So in your code:
var app = angular.module('plunker', []);
app.controller('MainCtrl',["$scope","DefaultName","TraitService", function($scope, defaultName, traitService) {
$scope.name = defaultName;
$scope.OKPressed = function() {
traitService.setName($scope.name);
};
});
// You can use .constant() for a constant value;
app.constant("DefaultName", "tom");
app.service('TraitService', function() {
var traitService = {}; // The name does't matter
traitService.setName = function(name) {
// Not this.name = name because (this)is not guaranteed to persist or be the same across injections.
// I am only using local storage to illustrate. I usually use $rootScope to store
// Global variables. since they are always available on the $scope object without
// needing a service.
// That might be a better way for you ($rootScope)
localStorage.setItem("nameKey", name);
}
traitService.getName = function () {
return localStorage.getItem("nameKey");
}
return traitService; // This is what will be injected above
});

Inject environment details into AngularJS controller

Let's take the example from AngularJS tutorial
function PhoneListCtrl($scope, $http) {
$http.get('phones/phones.json').success(function(data) {
$scope.phones = data;
});
$scope.orderProp = 'age';
}
//PhoneListCtrl.$inject = ['$scope', '$http'];
Now, lets say I don't want to hard code the url 'phones/phones.json' and would prefer the page which hosts this controller to inject it, what should be the right way of doing the same in Angular JS?
There are a lot of ways to do this... the simplest way would just be to use $window, so you'd inject the $window service, and that's basically just the global $window that's been injected. Then you can register those paths as window.path = 'whatever.json'; and you'll be fine:
window.path = 'some/path.json';
function PhoneListCtrl($scope, $http, $window) {
$http.get($window.path).success(function(data) {
$scope.phones = data;
});
$scope.orderProp = 'age';
}
A more advanced way would be to create a module with a service that you inject into your app, in this case each page would have it's own module:
//create your module.
angular.module('configData', [])
.factory('pathService', function () {
return {
path: 'some/path.json'
};
});
//then inject it into your app
var app = angular.module('myApp', ['configData']);
app.controller('PhoneListCtrl', function($scope, $http, pathService) {
$http.get(pathService.path).success(function(data) {
$scope.phones = data;
});
$scope.orderProp = 'age';
});
You can, of course, do anything in between the two. I would suggest taking the path that is the most maintainable while still easy to test.

Categories