Angular .Value not working - javascript

New to Angular and I am trying to figure out Value. I am trying to save a value that I can later inject into my controller but for some reason, it breaks. If you run the plnkr sample, it will work, code gets to the controller. If you comment out line 68 and un-comment 67, it breaks the application. Line 41, I just set a value which is what I want to pass into my controller.
Why would this not work?
http://plnkr.co/edit/SnOm2r?p=options

There is no AppConfig...if you want to inject AppConfig it has to exist somewhere, a directive, a service, a factory, SOMETHING. You don't currently have one being loaded.

Your issue is a timing issue. The controller is created before the value is set so it doesn't have access.
If you create like this:
var mainApp = angular.module("Test", ["ui.router"]);
mainApp.value("AppConfig", 1.0);
Then you can access it right away. If you have to set it asynchronously (i.e. you plan to set it as the result of a call) then the best way is probably to inject the $injector instead of the AppConfig. Then you can do:
if ($injector.has("AppConfig")) { value = $injector.get("AppConfig"); }
Even better may be to move that into a service with a promise that can return the value once it's fetched then cache it for subsequent calls.

Related

Global variable in AngularJS (good practice)

I'm looking for a pattern in order to have globals constant in my application. But not with a controller or a factory. (so not with app.constant() too)
I just want to set a variable but I didn't find something good.
I wanted to set this var in my rootScoop but without success.
with something like
myApp.run(function($rootScoop){
$rootScoop.global = {};
});
When I use that code, an arror occurs for nothing (transtateFilterProvider). When I delete this code, the translateService works,
I MUST have access in all html view, I don't want to always use a controller (useless in this case), I just want to set a global variable in rootScoop.
Thank you.
You are getting an error because it is :
$rootScope
And not
$rootScoop
Anyway, correct way to do this is to add a constant module to your app like :
angular.module('yourapp', []).constant('Constants', {
foo: 'bar'
});
But you'll have to call Constants in controllers.
If you use $rootScope, remember you will need to call $root.global in templates.

Angularjs, do something when document loads

I am developing an angular js application, and i need to run a function, via service provider, before everything else. The function is a get request, which returns two variables in JSON, which returns either true orfalse.
If the variable is true, then load another state (i am using ui router). How can i do that?
In angular the document loaded is not really has a good usage, because it is a framework and the we need to count on angular loaded/ready instead. Use angular.module('yourApp').run() like below:
var app = angular.module('yourApp');
app.run(['$rootScope', '$http', function($rootScope, $http){
$http('http://localhost/status/').then(function(res){
$rootScope.somethingStatus = res; // assuming that your response is either true of false.
});
$rootScope.$watch('somethingStatus', function(nv){
// here is where you know your request has been done...
if(nv === true) {
// ...
}
else if(nv === false) {
// ...
}
});
}]);
NOTE: please aware what run in app.run() will be fired before any controller initialing or view rendering. So later on when you want to access the value of what you been got. Inject $rootScope to the controller (or any place) when you needed it.
EDIT: fix some typos. Updated answer again, credit to #georgeawg and #Pierre Emmanuel Lallemant. Thanks you guys for the correction
You should write a controller for the page where you do the request (in order to display something to the user), with a default html view, and when you receive the response, then you change the state to use the desired controller.

angular how to use scope from a different controller

I have a user.list.ctrl and a user.detail.cntr. All the controllers are build as a module and are injected in a "user-module" which I inject in the app.js. (see the complete code in the plunker below)
my controller module
angular.module('user-module', ['user-module.controllers']);
my user-module
angular.module('demo.app', ['user-module']);
In both controllers i inject user-Fctr with data from a REST factory. (works well)
user.list.cntrl has a $scope.refresh()
user.detail.cntrl has a $scope.update()
user.list.cntrl
When I enter a new record, i call the $scope.refresh() so I can refresh the list. (this is working fine)
user.detail.cntrl
When i click a user from the list, the user detail loads in a different view (works ok)
when I update the user.detail, I want to call $scope.refresh() to update the user.list , but it is not working. I cannot call $scope.refresh()
I thought that since I inject the same factory into both controllers I can use each others $scopes.
Any ideas on how I can use $scope.refresh() (or update the list when I update the user.detail.js)
I make a plunker with all the js files (the plunker is not functional, it is only to show the code that I have)
http://plnkr.co/edit/HtnZiMag0VYCo27F5xqb?p=preview
thanx for taking a look at this
This is a very conceptual problem.
You have created a controller for each "piece" of view because they are meant for different activities. This is the purpose of controllers. So that is right.
However, you are trying to access the refresh function, written in one controller, in another one. Taken literally, this is wrong, since then, refresh is out of place either inside the user list controller or the detail controller.
A function that is meant to control (literally) what is happening on a specific piece of view is a controller. - There you are right having a controller for the list and one for the details.
A function that is meant to be shared between controllers must be a service. This is exactly what you want for your refresh function to be.
Whenever you inject the same factory into n controllers, you can't use the scope of every controller. This isn't the purpose of a controller.
However, whenever you inject the same factory into n controllers, you can use its exposed methods.
The problem you have, can be solved as follows:
app.factory( 'sharedFunctions', [ 'factoryId', function sharedFunctions( factoryId ) {
var refresh = function () {
factoryId.getAll(/*your params to query*/)
.success( function ( response ) {
//This will return the list of all your records
return response;
});
};
return sharedFunctions;
}]);
With this factory service registered, then you can inject it to your controllers and whenever you need to refresh, just call the exposed method of the service and plot the new information into the view.
Hope it works for you!
i ended up doing this:
I added in the list.contrl this:
factoryId.listScope = $scope;
since I already have the factoryId (my data service) injected in the detail controller, I can call this:
factoryId.listScope.refresh();
it works but I don't know if this is the best way. any comments?

How to change the same values everywhere - in service , controllers, outside angular?

service implementation
myService = function()
{
this.config = {
show0: false,
show1: true,
role : -1,
id : -1;
};
};
in controller, I map the config values
$scope.config = myService.config; //I guess this by reference, isnt it???
in templates of these controllers for e.g. the $scope.config.show0 is used with for e.g. ng-model
Now outside angular in my threejs code
I get the service using injector which I have defined earlier and change some values depending on certain conditions
var service = window.my.injector.get('myService');
service.config.id = 1991;
Now this value is not immediately reflected in the HTMl template,
Source = {{config.id}} still renders as Source = -1
But when I click on some other button in the same template which is mapped to any other value in the same scope
Source = {{config.id}} still renders as 1991
How should I force this rerendering or refreshing in my non angular code soon after
var service = window.my.injector.get('myService');
service.config.id = 1991;
///do something to refresh that controller
Am I using the service wrong? How should I make this config available in angular controllers, templates and non angular code if not via a service?
Shouldnt changing the $scope.config properties values and changing the values outside angular by retrieving the service via injector change the values everywhere ?
This is because the angular digest cycle does not kick in from your threejs code. I am not sure where your three js code is, but try using $scope.$apply to kick in the digest cycle, and it should work fine.
If you can share a jsFiddle, I can have a better understanding on what you are trying to achieve, but the reason why this is not happening is, as I said, that the digest cycle does not kick in.

angularJs - won't show data until user types in search field

Final Solution? It looks like I had my routing and controllers a little confused. I had my routing in a file with my controller module. I moved my routeProvider into the main module, like in the tutorial example. My controller and my routeProvider where under the same module. Maybe that was confusing everything. So now I have the controller in it's own module, and the routeProvider is under the main module. That seems to have fixed the problem without needing to initialize the search field to force the bindings to update the data.
Update:
The solution to showing my data at the time the page loads was to use an older version of angularJs, or use ng-Init and initialize the search field to a blank space.
I'm getting JSON data from the firebase website to update a table. I have a search field that works. The data will not display in the table until I type something into the search field. I don't know why the data won't just display in the table as soon as the controller is done getting the data.
Note: The link to the backend data is now removed, I don't want to keep that database file there indefinitely.
Here is the link to the jsFiddle code:
Last Version jsFiddle
Here is code for the controller.
'use strict';
/* App Module */
// Create the module named 'testApp'
var testApp = angular.module('theTestApp', [
'ngRoute',
'testServices'
]);
'use strict';
/* Services */
var testServices = angular.module('testServices', []);
testServices.controller('CommonController',
// function($scope, $http, $route) {
function($scope, $http) {
//access the customInput property using $route.current
//var dbKey = $route.current.customInput;
var dbKey = 'test-a-db-12345';
var urlToDb = 'https://' + dbKey + '.firebaseio.com/rows/.json';
$http.get(urlToDb).success(function(data) {
$scope.UsedItems = data;
});
});
How do I get the data to display as soon as it's loaded?
Update 1: I'm assuming that the data is already there, but the event of typing something into the search field triggers the filter, and then the data shows up. It shows up filtered.
Update 2: I'm reading about $Watch There is constantly and event loop listening for events. When a key is pressed in the search box, the bindings {{name}} get updated if something has changed. In this case, the content of the search input field was changed. So the issue seems to have something to do with when the bindings get updated, not whether the data is getting retrieved.
Update 3:
This version of the code runs. It loads the data when the page is rendered. Here is a working example in jsBins.
Update 4:
As of angularJs version 1.2.0 the behavior changes. Versions 1.0.8, 1.0.7 will instantly display my data when the page loads, 1.2.0 will NOT! I just happened to be using jsBins which uses 1.0.7, and it started working. Didn't know why until I started comparing the differences. Hopefully, there is a way to make it work in newer versions.
jsBins Working Example
The problem is that theSearch.Txt is empty. And you are filtering by that. My guess is that Angular at that moment decides to not let anything through and thus doesn't display anything.
What you should do:
Initialize the variable with a space filled string. (i.e. ' ')
Here is a working jsFiddle.
I used ngInit here. But that is because you decided to link?? the controller instead of putting it into a script tag. I suggest that next time you rather take the additional effort into pasting it in, as using the ngInit directive makes me feel like using eval.
Try
$scope.$apply(function(){
$scope.UsedItems=data;
}

Categories

Resources