I've looked at a half dozen examples, but none of them seems to work for me - maybe because of the peculiar var myController = [] format of the code I inherited.
.cshtml:
<div id="ng-app" ng-app="cmorApp">
<div
data-ng-controller="myCtrl"
data-ng-init="referralId = #Model.ReferralId">
...
This works, inasmuch as my page correctly renders the value I seek:
data-ng-init="referralId = 12345"
Now I'm just trying to capture it in my controller.
Controller:
var myCtrl = ['$scope', '$http', 'FileUploader',
function ($scope, $http, FileUploader, referralId) {
console.log(referralId);
//$scope.init = function (referralId) {
// console.log(referralId);
//}
//$scope.init();
It outputs undefined.
What am I missing?
.
UPDATE:
This sort of works:
ng-init="init(#Model.ReferralId)
.
$scope.init = function (referralId) {
$scope.referralId = referralId;
}
The problem is, the value is not there when I need it. It only there if I let the page do some processing.
I can't do this, or I'm back to undefined:
$scope.init = function (referralId) {
$scope.referralId = referralId;
}
console.log($scope.referralId);
Related
My code is as shown below:
angular.module('xyz', [])
.controller('listController', ['$scope',
function($scope) {
$scope.deliveryOptions = 0;
var vm = this;
function doTransaction() {
console.log('delivery options is ' + vm.$scope.deliveryOptions);
}
}
]);
Here inside console.log(delivery options), it gives me error that it is Unable to get property 'deliveryOptions' of undefined or null reference. So how can I access that variable?
The problem is that the $scope is not defined on the vm object.
To solve this you should either define everything on the $scope object like this
angular.module('xyz', [])
.controller('listController', ['$scope',
function($scope) {
$scope.deliveryOptions = 0;
$scope.doTransaction = function() {
console.log('delivery options is ' + $scope.deliveryOptions);
}
}
]);
Or on the vm object
angular.module('xyz', [])
.controller('listController',
function() {
var vm = this;
vm.deliveryOptions = 0;
vm.doTransaction = function() {
console.log('delivery options is ' + vm.deliveryOptions);
}
}
);
Mixing vm and $scope is not the best way to go
Use either $scope or controller as, not both
The primary issue is you're mixing original AngularJS 1.x $scope usage, with the controller as design pattern that uses vm (meaning "view model"), which started with Angular 1.5.
You need to pick one or the other, and then your code will work just fine.
If you go with the cleaner and less error-prone vm and controller as design pattern, you simply use vm rather than $scope:
angular.module('xyz', [])
.controller('listController', function() {
var vm = this
vm.deliveryOptions = 0
vm.doTransaction = function() {
console.log('delivery options is ' + vm.deliveryOptions)
}
})
And then in your view, you use vm.doTransaction() to call your function and display your variable.
Ok, I know the following code is wrong since it's not working. But hopefully it'll help describe what I'm trying to do:
Choose a new background color for the site:
<select name="bgcolor" onChange="ModifyColorsInLess();" id="bgcolor" ng-change="changeCurrent('bgcurrent');">
<option ng-repeat="color in colorlist" value="{{color}}" ng-selected="color==bgcurrent" >{{color}}</option>
</select>
Now, you'll see I have two things that I want to happen on a selection.
1) Hit the JS function ModifyColorsInLess() which this does and does perfectly. The function is sitting in a regular JS file. This changes the actual value of a LESS variable immediately.
2) Hit the function in the controller of changeCurrent(). This is an attempt to change the value of a scope variable set in the Angular controller.
I'm trying to figure out how to make the code do both.
EDIT:
Controller code:
app.controller('HomeController', ['$scope', '$location', '$sce', '$routeParams', '$timeout', function($scope, $location, $sce, $routeParams, $timeout ) {
// Configuration Variables:
$scope.title = "Site Title";
$scope.logosrc = "images/site_logo.gif";
$scope.tagline = "This is the new tagline!!!";
$scope.bgcurrent = "White";
$scope.pccurrent = "Black";
$scope.sccurrent = "LightGray";
$scope.dtccurrent = "Black";
$scope.ltcurrent = "LightGray";
// This changes the shadowed aspect of the top nav and footer based on a checkbox
$scope.shadowChange = function(cb){
var isChecked = (document.getElementById('shadow').checked);
if(isChecked){
$('#footer').addClass('shadowed');
$('.nav').addClass('shadowed');
$('.show-menu').addClass('shadowed');
}else{
$('#footer').removeClass('shadowed');
$('.nav').removeClass('shadowed');
$('.show-menu').removeClass('shadowed');
};
return true;
};
// This converts any HTML code in the text to actual code so that it renders properly
$scope.renderHtml = function(html_code)
{
return $sce.trustAsHtml(html_code);
};
// This sets a default value for the passed parameter. $routeParams.action in this example
if(!(typeof $routeParams.action === 'undefined')){
$scope.pageAction = $routeParams.action;
}
else{
$scope.pageAction = "home";
}
// This changes a default color
$scope.changeCurrent = function(varname){
alert(varname);
// $scope[varname] = valname;
};
}]);
here's my issue: I want to run the code of controllerB into controllerA. The issue is that while the variables are returned to the controllerA, the values from requests are never returned. Here's a plunker to show the issue: http://plnkr.co/edit/GqC9BOKTi8HxQLf2a2yd?p=preview
var test = $scope.$new();
$controller('Ctrl1', {$scope : test});
//the first 2 lines are executed, but the 3d never returns a value
$scope.variable = test.variable;
$scope.varFromFunction = test.varFromFunction();
$scope.varFromRequest = test.varFromRequest;
The first 2 lines execute, but the 3d one never returns a value.
Since varFromRequest is located inside a $timeout method in the first controller with 500ms, it will execute 500s later meanwhile angular completes its linking phase.
Watching varFromRequest in the second controller is the easy solution
test.$watch('varFromRequest', function(new_value, old){
$scope.varFromRequest = test.varFromRequest;
})
Here is the updated plunker http://plnkr.co/edit/TqSjeckrdqeKquEbCwFX
The varFromFunction is undefined when the second controller tries to get a reference. The timeout sets this var after this request. If you delay the request for reference then you will get the appropriate value. This isn't the recommended way of working but it does answer your question why it hasn't been set yet.
myApp.controller('Ctrl1', ['$scope', '$timeout', function($scope, $timeout) {
$scope.variable = 'OH HAI';
$scope.varFromFunction = function(){
return "OH HAI FromFunction";
}
$timeout(function(){
$scope.varFromRequest = "time";
},500);
}]);
myApp.controller('Ctrl2', ['$scope', '$controller', '$timeout', function($scope, $controller, $timeout) {
var test = $scope.$new();
$controller('Ctrl1', {$scope : test});
$scope.variable = test.variable;
$scope.varFromFunction = test.varFromFunction();
$scope.varFromRequest = test.varFromRequest || 'unset';
$timeout(function(){
$scope.varFromRequest = test.varFromRequest || 'still unset';
},500);
}]);
I have a filter that is not returning anything when it is run on an array from a factory. But when I copy paste the array directly into the filter, it works fine. There must be a simple solution, and it is driving me crazy.
This works:
$filter('filter')([
{"name":"firstItem","code":"one"},
{"name":"secondItem","code":"two"},
{"name":"thirdItem","code":"three"}
],"two",true);
This doesn't:
$filter('filter')($scope.items,"two",true);
Angular sample:
angular.module('App', ['ngResource'])
.controller('Ctrl', function($scope, $filter, Items) {
$scope.items = Items.query();
var codeToFilter = "two";
$scope.badFilter = $filter('filter')($scope.items,codeToFilter,true);
$scope.goodFilter = $filter('filter')([
{"name":"firstItem","code":"one"},
{"name":"secondItem","code":"two"},
{"name":"thirdItem","code":"three"}
],"two",true);
})
.factory("Items", function ($resource) {
return $resource("item-list.asp");
});
And the array returned from item-list.asp:
[{"name":"firstItem","code":"one"},{"name":"secondItem","code":"two"},{"name":"thirdItem","code":"three"}]
This is what I see on the page:
Bad Filter: []
Good Filter: [{"name":"secondItem","code":"two"}]
Items.query() is async and hence not resolved instantly. At the time your filter is hit, it's not populated.
Set it up like this:
Items.query(function(result) {
$scope.items = result;
$scope.badFilter = $filter('filter')($scope.items,codeToFilter,true);
});
try this it adds in the array to the control to help pass in information to the function.
.controller('Ctrl', ['$scope', '$filter', 'Items', function($scope, $filter, Items) {
and then don't forget to close the square bracket after the functions close curly brace
I'm attempting to understand how factories work and have hit a road block. I'm following along with this guide on page 88 or so.
Running my code results in these console errors.
TypeError: Cannot read property 'getData' of undefined
<div ng-app="timeEntry">
<div ng-controller="timeEntryController">
<p class="lead">Factory Test</p>
<p>**** {{testing}}</p>
<p>******** {{testing2}}</p>
</div>
</div>
var timeEntry = angular.module('timeEntry', []);
timeEntry.controller('timeEntryController', ['$scope', function ($scope, loadData) {
$scope.testing = 'test';
$scope.testing2 = loadData.getData();
}]);
timeEntry.factory('loadData', function ($http) {
var test = 'test data';
var factory = {};
factory.getData = function () {
return test;
};
return factory;
});
JS Fiddle http://jsfiddle.net/dgdavidson/QPc3j/2/
I'm sure that the error will be frightfully obvious, but I don't know what it is.
You need to add the string 'loadData' to your declaration:
So change this:
timeEntry.controller('timeEntryController', ['$scope', function ($scope, loadData) {
to:
timeEntry.controller('timeEntryController', ['$scope', 'loadData', function ($scope, loadData) {
(updated fiddle)
The error you're seeing is because Angular is passing undefined into loadData. And, of course, undefined has no property getData.
This is such an easy/common mistake that some people skip manually declaring the strings and use ngMin to do it for them (for instance adding it to your grunt file). This allows you to then use the following style of declaration where you don't have to ensure strings match parameters:
timeEntry.controller('timeEntryController', function ($scope, loadData) {