I work with AngularJS Google Maps and need to configure the api_key in the module config part (question similar to this one).
My question is about configuring AngularJs modules
This is my test pen:
var app = angular.module('myapp', [])
/*
// HERE ?????
// I try to pass a value from the HTML (server side)
.config(function($window){
console.log($window.memKey);
})
*/
.controller('MainCtrl', ['$scope', '$window', function($scope, $window) {
$scope.name = $window.memName;
$scope.city = $window.memCity;
$scope.getMember = function(id) {
console.log(id);
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script type="text/javascript">
var memKey = 'bb7de28f-0f89-4f14-8575-d494203acec7';
var memName = 'John';
var memCity = 'New-York';
</script>
<div ng-app="myapp" ng-controller="MainCtrl">
Member name: {{name}} <br>
Member city: {{city}}
</div>
How is possible to recuperate the memKey value from the HTML (Server) side?
your memKey is in an accesible scope, according on how you've declared it.
just do
app.config(function(){
console.log(memKey);
})
See snippet
You can access an existing angular module if you don't use the injection array. After you have the reference, you can declare constants eg:
<script type="text/javascript">
var app = angular.module('myapp');
app.constant('memKey', 'bb7de28f-0f89-4f14-8575-d494203acec7');
app.constant('memName', 'John');
app.constant('memCity', 'New-York');
//Or do them as one config object
</script>
--
.config(['memKey', 'memName','memCity' function(memKey, memName, memCity) {
}]);
Related
as you can see I have opened .xml file and parsed it to a xmlDoc. What I am trying to achieve is that this xmlDoc will be accessible from the whole script(I want to make some functions later which will be displaying elements from .xml to a screen). I searched the web and find that it is possible via global variable $rootScope but couldn't implement it correctly. I hope you guys can help me. Thanks.
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body ng-app="myApp">
<p id="title">asd</p>
<button name="opt1" ng-click="">YES</button>
<button name="opt2" ng-click="">NO</button>
<script>
var app = angular.module('myApp', []);
var parser, xmlDoc;
app.run(function($rootScope, $http) {
text = $http.get("file.xml").then(function(response) {
return response.data;
}).then(function(text) {
parser = new DOMParser();
xmlDoc = parser.parseFromString(text,"text/xml");
document.getElementById("title").innerHTML =
xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;
});
});
</script>
</body>
</html>
There are many ways in angular to declare and use a global variable.
examples:
1. By using $rootScope.
we need to add a dependency in our controller or service like:
app.controller('myCtrl', ['$rootScope', '$scope', function($rootScope, $scope){
$rootScope.yourVar = 'YourValue';
....
....
}]);
and then You can use this `yourVar` variable anywhere in your code.
Another way is by using angular factory or servive.
app.factory('factoryObj', ['$scope', function($scope){
let factoryObj.yourVar = 'yourValue';
return factoryObj;
}]);
Now in any controller or any other service, by using this factoryObj as a dependency and then inside that controller or service we can use factoryObj.yourVar as a variable. as:
app.controller('myCtrl',['$rootScope','$scope','factoryObj'function($rootScope,$scope, factoryObj){
console.log('factoryObj.yourVar value: ',factoryObj.yourVar);
}]);
I am wondering at the dual behaviour of $scope. In the below script I am getting value of name as alert. But in my ionic app the same code alerts undefined.
I googled the problem and found this link as a solution where it states that we need to use dot(.) in order to get the value in ng-model. What is the difference between two.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.a =function a(){alert($scope.name);}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
Name: <input ng-model="name" ng-blur="a()">
</div>
Try changing your controller function as below:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.a =function(){
alert($scope.name);
}
});
Actually it does work with Ionic,
angular.module('starter.controllers', [])
.controller('myCtrl', function($scope) {
$scope.a = function a() {
alert($scope.name);
}
})
DEMO
Solution :
"If you use ng-model, you have to have a dot in there."
Make your model point to an object.property and you'll be good to go.
Controller
$scope.formData = {};
$scope.check = function () {
console.log($scope.formData.searchText.$modelValue); //works
}
Template
<input ng-model="formData.searchText"/>
<button ng-click="check()">Check!</button>
This happens when child scopes are in play - like child routes or ng-repeats.
The child-scope creates it's own value and a name conflict is born as illustrated here:
See this video clip for more: https://www.youtube.com/watch?v=SBwoFkRjZvE&t=3m15s
.
And that is referred from below links :
Other Solutions
Use this keyword instead of $scope, More details
And also you can get more details from this below two discussions
Ng-model does not update controller value
Why is my ng-model variable undefined in controller?
Update Solution 1 :
Please declaring the blank object first at the top of your controller:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.name = "";
$scope.a = function(){alert($scope.name);}
});
I hope these will be helps to you.
Try to use json object.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.user = {'name':''};
$scope.a =function a(){alert($scope.user.name);}
});
<div ng-app="myApp" ng-controller="myCtrl">
Name: <input ng-model="user.name" ng-blur="a()">
</div>
So I'm trying to play with basic angular code so that I can get a feel for how to create and declare controllers for the project I'm working on. I took some sample code from the angularjs.org controller tutorial and ran into a few issues (turns out I didn't have "./angular.min.js" originally). But I finally got my page to work properly after fixing that.
Then I tried to split the code up so my app.js file could know what controllers to use and I could put the controller code in a separate file (having never made a controller before). After I did this the page gave a console error Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.5.8/$injector/modulerr?p0=spicyApp1&p1=Error%…FUsers%2FRDubz%2FDesktop%2Fcontroller%2520test%2Fangular.min.js%3A21%3A179) and I can't figure out what's wrong. I just want to be able to put the controller code into another file.
app.js with controller code:
var myApp = angular.module('spicyApp1', []);
myApp.controller('SpicyController', ['$scope', function($scope) {
$scope.spice = 'very';
$scope.chiliSpicy = function() {
$scope.spice = 'chili';
};
$scope.jalapenoSpicy = function() {
$scope.spice = 'jalapeño';
};
}]);
app.js without controller code:
var spicyApp1 = angular.module('spicyApp1.controllers', []);
testController.js
angular.module('spicyApp1.controllers').controller('SpicyController', ['$scope', '$http', function($scope, $http){
$scope.spice = 'very';
$scope.chiliSpicy = function() {
$scope.spice = 'chili';
};
$scope.jalapenoSpicy = function() {
$scope.spice = 'jalapeño';
};
}]);
blank.html
<title>Example - example-controller-spicy-1-production</title>
<script src="./angular.min.js"></script>
<script src="./app.js"></script>
<script src="./testController.js"></script>
</head>
<body ng-app="spicyApp1">
<div ng-controller="SpicyController">
<button ng-click="chiliSpicy()">Chili</button>
<button ng-click="jalapenoSpicy()">Jalapeño</button>
<p>The food is {{spice}} spicy!</p>
</div>
</body>
</html>
Try this:
File 1:
angular.module('spicyApp1', []);
File 2:
angular.module('spicyApp1').controller('SpicyController', ['$scope', '$http', function($scope, $http){
$scope.spice = 'very';
$scope.chiliSpicy = function() {
$scope.spice = 'chili';
};
$scope.jalapenoSpicy = function() {
$scope.spice = 'jalapeño';
};
}]);
In your html file
call the file 1, file 2 and so on...
I am new to AngularJS I have a problem with this code. I want to add multiple controller in single ng-app. But it execute first one. Why not second one?
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angul /1.4.8/angular.min.js"></script>
</head>
<body>
<div ng-controller="cont1">
<input type="text" ng-model="fullname">
{{fullname}}
</div>
<div ng-controller="cont2">
<input type="text" ng-model="fname">
{{fname}}
</div>
<script>
var app = angular.module("myapp", []);
app.controller('cont1', function ($scope) {
$scope.fullname = "";
});
var new = angular.module('myapp', []);
new.controller('cont2', function ($scope) {
$scope.fname = "";
});
</script>
</body>
</html>
Because you are overwriting the first myapp module when you do var new= angular.module('myapp',[]);.
Your code should be:
var app = angular.module("myapp", []);
app.controller('cont1', function($scope) {
$scope.fullname = "";
});
app.controller('cont2', function($scope) {
$scope.fname = "";
});
or
var app = angular.module("myapp", []);
app.controller('cont1', function($scope) {
$scope.fullname = "";
});
angular.module("myapp").controller('cont2', function($scope) {
$scope.fname = "";
});
The second parameter[] passed to module() makes the difference
To best way to define controllers, directives, factories etc... is
define your modules names in a separate file
app.module.js
angular.module("myapp",[]); // inside [] you define your module dependencies
for controllers create separate file (depending on your requirement even you can create 1 file for 1 controller)
some.controller.js
angular.module("myapp").controller('someCtrl'['$scope', function($scope){
}]);
angular.module("myapp").controller('someOtherCtrl'['$scope', function($scope){
}]);
NOTE:
Two types you can write controller
TYPE1 (not recomended)
.controller('ctrlName', function($scope){
});
TYPE2 (recomended)
.controller('ctrlName', ['$scope', function($scope){
}]);
Reason
So as you can see in the TYPE2 we are passing controller dependencies in an array, so when we compile our program angular will give the name as eg:a to $scope inside function() and treat it as $scope.
With the TYPE1 you need to follow specific order while defining controller dependency otherwise angular will through error because in this approach angular simply treats first dependency as $rootscope, second as $scope and so on....
For Eg:
you can't pass dependencies to your controller like this
.controller('ctrlName', function($http, $scope) {
});
this will throw error
if you define like
.controller('ctrlName', function($scope, $http) {
});
this will work fine since its in order that angular wants.
You can define multiple controllers in a single module in this way also:
angular.module("myapp",[]);
.controller('cont1',function($scope){
$scope.fullname="";
});
.controller('cont2',function($scope){
$scope.fname="";
});
When you are defining modules, don't use var. You can find some of the Angular best practices here: Angular Style Guide/Best Practices
I've built an app with firebase that can login a user and attain their id, but I can't figure out how to incorporate this with a user making a submission of a string.
See Code pen here: http://codepen.io/chriscruz/pen/OPPeLg
HTML Below:
<html ng-app="fluttrApp">
<head>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.1/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
<script src="https://cdn.firebase.com/js/client/2.0.2/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/angularfire/0.9.0/angularfire.min.js"></script>
</head>
<body ng-controller="fluttrCtrl">
<button ng-click="auth.$authWithOAuthPopup('google')">Login with Google</button>
<li>Welcome, {{user.google.displayName }}</li>
<button ng-click="auth.$unauth()">Logout with Google</button>
<input ng-submit= "UpdateFirebaseWithString()" ng-model="string" ></input>
Javascript Below:
<script>
var app = angular.module("fluttrApp", ["firebase"]);
app.factory("Auth", ["$firebaseAuth", function($firebaseAuth) {
var ref = new Firebase("https://crowdfluttr.firebaseio.com/");
return $firebaseAuth(ref);
}]);
app.controller("fluttrCtrl", ["$scope", "Auth", function($scope, Auth) {
$scope.auth = Auth;
$scope.user = $scope.auth.$getAuth();
$scope.UpdateFirebaseWithString = function () {
url = "https://crowdfluttr.firebaseio.com/ideas"
var ref = new Firebase(url);
var sync = $firebaseAuth(ref);
$scope.ideas = sync.$asArray();
$scope.ideas.$add({
idea: $scope.string,
userId:$scope.user.google.id,
});
};
}])
</script>
</body>
</html>
Also assuming, the above dependencies, the below works to submit an idea, but the question still remains in how to associate this with a user. See codepen here on this: http://codepen.io/chriscruz/pen/raaENR
<body ng-controller="fluttrCtrl">
<form ng-submit="addIdea()">
<input ng-model="title">
</form>
<script>
var app = angular.module("fluttrApp", ["firebase"]);
app.controller("fluttrCtrl", function($scope, $firebase) {
var ref = new Firebase("https://crowdfluttr.firebaseio.com/ideas");
var sync = $firebase(ref);
$scope.ideas = sync.$asArray();
$scope.addIdea = function() {
$scope.ideas.$add(
{
"title": $scope.title,
}
);
$scope.title = '';
};
});
</script>
</body>
There a couple of things tripping you up.
Differences between $firebaseand $firebaseAuth
AngularFire 0.9 is made up of two primary bindings: $firebaseAuth and $firebase. The $firebaseAuth binding is for all things authentication. The $firebase binding is for synchronizing your data from Firebase as either an object or an array.
Inside of UpdateFirebaseWithString you are calling $asArray() on $firebaseAuth. This method belongs on a $firebase binding.
When to call $asArray()
When you call $asArray inside of the UpdateFirebaseWithString function you will create the binding and sync the array each time the function is called. Rather than do that you should create it outside of the function so it's only created one item.
Even better than that, you can abstract creation of the binding and the $asArray function into a factory.
Plunker Demo
app.factory("Ideas", ["$firebase", "Ref", function($firebase, Ref) {
var childRef = Ref.child('ideas');
return $firebase(childRef).$asArray();
}]);
Get the user before the controller invokes
You have the right idea by getting the user from $getAuth. This is a synchronous method, the app will block until the user is returned. Right now you'll need to get the user in each controller. You can make your life easier, by retrieving the user in the app's run function. Inside of the run function we can inject $rootScope and the custom Auth factory and attach the user to $rootScope. This way the user will available to all controllers (unless you override $scope.user inside of your controller).
app.run(["$rootScope", "Auth", function($rootScope, Auth) {
$rootScope.user = Auth.$getAuth();
}]);
This is a decent approach, but as mentioned before $scope.users can be overridden. An even better way would be to resolve to user from the route. There's a great section in AngularFire guide about this.
Associating a user with their data
Now that we have the user before the controller invokes, we can easily associate their id with their input.
app.controller("fluttrCtrl", ["$scope", "Ideas", function($scope, Ideas) {
$scope.ideas = Ideas;
$scope.idea = "";
$scope.UpdateFirebaseWithString = function () {
$scope.ideas.$add({
idea: $scope.idea,
userId: $scope.user.google.id,
}).then(function(ref) {
clearIdea();
});
};
function clearIdea() {
$scope.idea = "";
}
}]);