Put local variable in angular.forEach loop in the global - javascript

Hello I have created a variable inside the angular.forEach loop that I need outside the loop to bind to the $scope, but i don´t know how to get outside this variable miAlumno.
Thanks.
'use strict';
angular.module('jarciaApp')
.controller('alumnoCtrl', function($routeParams, $firebaseArray) {
var ref = firebase.database().ref('PrimeroA');
var JarciaArray = $firebaseArray(ref);
var id = $routeParams.id;
var curso = $routeParams.curso;
var miAlumno;
JarciaArray.$loaded()
.then(function(miAlumno) {
angular.forEach(JarciaArray, function(alumno, miAlumno) {
if (alumno.Id == id) {
var miAlumno = alumno;
}
})
});
console.log(miAlumno);
});

Don't declare variable miAlumno in loop. Declare it outside and it will be visible.
Pay attention at that console.log(miAlumno), it probably will be always null because of the asynchronous assignement.

If I understand correctly, you are wanting to use the alumno variable you have passed into the function outside the scope of that function?
You can go about it by creating/declaring a global variable outside the function just as you did with miAlumno, then simply assign your global variable to the value your function produces. Also you have miAlumno declared twice, once outside as a global, then inside the for loop.
Apologies if I'm misunderstanding, and if so, please elaborate.

It sounds like you're using the ControllerAs syntax, which means what traditionally would be scope variables are automatically bound as properties of the controller. You can simply set the variable inside of the loop, using a cached value of this:
'use strict';
angular.module('jarciaApp')
.controller('alumnoCtrl', function($routeParams, $firebaseArray) {
var ref = firebase.database().ref('PrimeroA');
var JarciaArray = $firebaseArray(ref);
var id = $routeParams.id;
var curso = $routeParams.curso;
var me = this;
JarciaArray.$loaded()
.then(function() {
angular.forEach(JarciaArray, function(alumno) {
if (alumno.Id == id) {
me.miAlumno = alumno;
}
});
// This will work to show the value
console.log(me.miAlumno);
});
// This still won't work, since $loaded is asynchronous
console.log(this.miAlumno);
});
I've also removed the extra attempts to pass miAlumno to the then function and the callback for forEach; those are unnecessary.
Do note the comments about console.log. I believe the $loaded() is asynchronous; thus it will not be set until whatever process that is actually finishes. If you move the log to inside the then(), you'll see the result.

Related

how to access global variable from function in javascript

I am trying to access global variable from function, i want to call variable outside from inside function variable.This is what I tried.
Note: the query function should be work after click on query function from html drop down selection.
Thank you for helping.
HTML
<select name="myInput" id="choice1">
<li><option value="6011">apib_cadastral:bivel</option></li>
<li><option value="6012">apib_cadastral:burhchaura</option></li>
</select>
javascript
var layer_name;
function query() {
var text_value = document.getElementsByName('myInput')[0];
var layer_name = text_value.options[text_value.selectedIndex].text;
}
query();
var config = {
geojson: layer_name,
};
Remove the "var" inside the function. With that you define a new variable that exists inside the function.
You should change your code in this way.
Because, when you re-declare variable inside query() it will occupy another cell from memory with different address. And, variable inside config object cannot access it. It will access layer_name [first defined] which contains undefined value
var layer_name ;
function query() {
var text_value = document.getElementsByName('myInput')[0]
layer_name = text_value.options[text_value.selectedIndex].text;
}
query();
var config = {
geojson: layer_name
}
In addition to other answers, which correctly state that you should remove var from the variable declaration inside the query() function, you could change the function to return the value, rather than relying on shared/global state.
function query() {
var text_value = document.getElementsByName('myInput')[0];
return text_value.options[text_value.selectedIndex].text;
}
var config = {
geojson: query()
};
Note that this may have a performance impact depending on how many times you call query() as the return value would have to be computed each time, but it's worth considering from the perspective of alleviating the need for shared/global state.
Also note, consider replacing var with more modern const and let...
const when the variable is initialised and never needs to change.
let when the variable needs to change beyond initialisation.
function query() {
const text_value = document.getElementsByName('myInput')[0];
return text_value.options[text_value.selectedIndex].text;
}
const config = {
geojson: query()
};

Is it bad practice to instantiate variables inside of $(document).ready as opposed to globally declaring them?

I'm trying to avoid the use of global variables in my code, so I'm trying to use a work around by declaring them inside of $(document).ready and passing them as parameters to functions outside of $(document).ready, updating them, and then returning the updated value from those functions to manipulate the variables inside of $(document).ready.
Another way around this is to use hidden input fields to store variables but I also heard that was bad practice.
I'm wondering if I should just use global variables, do it the way I'm currently doing it, or use hidden input fields?
Below is a brief example of what I'm trying to accomplish. The variable validations is the variable I want to be able to use and update.
$(document).ready(function(){
var validations = [];
$('#inp').keypress(function(e){
if(e.which == 13){
e.preventDefault();
scanValidation(validations, function(valid){
validations = valid;
});
}
});
}):
function scanValidation(valid, cb){
var scanval = $('#inp').val();
if(valid.includes(scanval)){
//display error
}
else{
var validarr = valid.slice();
validarr.push(scanval);
var myData=JSON.stringify({ "name":"user1", "validations":validarr});
//Makes an ajax call to see if the sent array validarr is a valid request
apiCall(myData,'scanValidation',function(decoded) {
if (decoded.Status!="ERROR") {
valid = validarr;
}
else {
//display error
}
return(cb(valid));
});
}
}
Any variables declared within the immediately executed function below will NOT be in the global scope.
(function () {
var someVar = 'someValue';
$(document).ready(function() {
});
})();
Is it bad practice to instantiate variables inside of $(document).ready as opposed to globally declaring them?
No, not at all! Variables should always be declared in the scope they're needed in, nowhere else.
Another way around this is to use hidden input fields to store variables but I also heard that was bad practice.
I've never heard of that, but yes it definitely sounds like a bad practise. That's just the same as a global variable, but a global variable stored in the DOM for some odd reason.
I'm trying to avoid the use of global variables in my code, so I'm trying to use a work around by declaring them inside of $(document).ready and passing them as parameters to functions outside of $(document).ready, updating them, and then returning the updated value from those functions to manipulate the variables inside of $(document).ready.
That, admittedly, is a bit weird.
The easiest way to improve this is to move the function declaration inside the ready handler as well, and just access the variable there directly - with the additional bonus of not having a scanValidation global variable:
$(document).ready(function() {
var validations = [];
function scanValidation() {
var scanval = $('#inp').val();
if (validations.includes(scanval)) {
//display error
} else {
var validarr = validations.slice();
validarr.push(scanval);
var myData = JSON.stringify({"name": "user1", "validations": validarr});
// Makes an ajax call to see if the sent array validarr is a valid request
apiCall(myData, 'scanValidation', function(decoded) {
if (decoded.Status!="ERROR") {
validations = validarr;
} else {
//display error
}
});
}
}
$('#inp').keypress(function(e){
if(e.which == 13){
e.preventDefault();
scanValidation();
}
});
});
If you want to make scanValidation reusable, so that it could be called from other places as well with its own array, I would suggest to create a factory function that creates validators, each of which is a closure over its own array. That way, the array is declared where it belongs, so that the user of the function does not have to store the state for them:
function makeScanValidator(display) { // any other configuration
var validations = [];
// returns closure
return function scanValidation(scanval) { // take it as an argument
if (validations.includes(scanval)) {
display(/* error */);
} else {
var validarr = validations.concat([scanval]);
var myData = JSON.stringify({"name": "user1", "validations": validarr});
apiCall(myData, 'scanValidation', function(decoded) {
if (decoded.Status!="ERROR") {
validations = validarr;
} else {
display(/* error */);
}
});
}
}
$(document).ready(function() {
var validate = makeScanValidator(function display() { … });
$('#inp').keypress(function(e){
if(e.which == 13){
e.preventDefault();
validate(this.value);
}
});
});

Updating a 'this' value in a service via a function

I'm quite new to Angular and am trying to understand how everything works. I've been poking around and couldn't find any information on how to do this. So, I've got a service that defines
this.totalCount = 0;
In my controller, my get request retrieves some emails and then executes a function called addMessage for each message it retrieves. The addMessage function is in my service.
The function in my service looks like this:
this.addMessage = function (messageObj) {
this.messagesList.push(messageObj);
}
Basically, I am trying to increment this.totalCount each time this function is executed so that it will update and then can be displayed in the view. I have it displaying in the view currently, however its number always remains 0.
I've tried the following:
1.
this.addMessage = function (messageObj) {
this.messagesList.push(messageObj);
this.totalCount++;
}
2.
var count = this.totalcount
this.addMessage = function (messageObj) {
this.messagesList.push(messageObj);
count++; //and then attempted to display this value in the view but with no luck
}
Any tips would be greatly appreciated.
try this:
var that = this;
this.addMessage = function (messageObj) {
that.messagesList.push(messageObj);
}
I assume that you're binding the var this way in your controller and your view
Service :
this.totalCount = 0;
this.totalCount++;
Controller :
$scope.totalCount = service.totalCount;
view :
{{totalCount}}
And if you're actually doing it like this, you should face this kind of trouble.
The main problem is that totalCount is a primitive var and doing this.totalCount++ will break the reference. If you want to keep some var you should bind it as a sub-object.
This way :
Service :
this.utils = {};
this.utils.totalCount = 0;
this.utils.totalCount++;
Controller :
//This is the most important part. You bind an object. Then even if you loose the totalCount reference, your object will keep its own reference.
$scope.myServiceUtils = service.utils;
View :
{{myServiceUtils.totalCount}}
Actually in service (it's a matter of taste) i prefer a lot to use the object syntax instead of this (as "this" can be confusing)
This way :
var service = {};
service.utils.totalCount = 0;
service.addItem = function(){
...
}
return service;
Hope that was your issue.
You pass argument to another function which has different scope than your service. It is trick with assigning current object to variable, which is visible from function.
var that = this;
this.addMessage = function (messageObj) {
that.messagesList.push(messageObj);
that.totalCount++;
}
Should work.
So you assign that variable with current object, which is visible in inner function scope.
In a function addMessage body, this refers to function scope which is new, and there is no compiler error, but messagesList is a null object and totalCount is incremented, but after program leave function, it's not visible in service, because it is in a function scope which isn't assigned to any variable.
To update service variable as it changes in your controller, use $watch.
$scope.$watch(function() {
return messagesService.totalCount;
}, function(new,old){
$scope.totalmessagecount = messagesService.totalCount;
});
First parameter of $watch if function which return observed for change element. Another is standard function to perform operation after update.

How to declare a variable accessible to whole function in angularjs?

(function (angular) {
'use strict';
angular
.module('app')
.controller('ListSharedContentCtrl', ['$scope','$log','UserService', 'ContractService','ContentOwnerService','PlatformPartnerService',function ($scope, $log, userService, contractService,contentOwnerService,platformPartnerService) {
$scope.init = function () {
var contractIds =[];
var contentOwnerId;
var platformPartnerId;
var user=userService.getCurrentUser('true');
var contentOwner=userService.isCurrentUserIsContentOwner();
var platformPartner=userService.isCurrentUserIsPlatformPartner();
if(contentOwner == "true")
{
contentOwnerService.getContentOwnerId().then(function(savedContentOwnerId) {
contentOwnerId=savedContentOwnerId;
console.log(contentOwnerId);//here I can log the value
},function(error) {
$log.error("Error fetching contract id:" + error.message);
});
}
console.log(contentOwnerId); //but Here I cant log the value..Its showing undefined
} $scope.init();
}]);
})(angular);
Now my question is how to make the scope of the variable "contentOwnerId" available to whole function?Please anyone help me I cant figure it out..Thanks in advance..!
You are declaring contentOwnerId twice; once inside the if block, once outside it. The one outside is declared, but never assigned a value. It should be null where it is showing null.
The reason why you are getting the contentOwnerId undefined is that it is undefined until when the getcontentOwnerId() promise succeed!
if you do
var contentOwnerId = "before resolving the promise";
at the beginning of your init() you will probably have that string logged to console, instead of undefined
use $scope.contentOwnerId instead of var contentOwnerId.
See $scope.contentOwnerId is available to whole controller i.e ListSharedContentCtrl.
normal javascript variable are limited to functions where as $scope is available to entire CONTROLLER
The .then() method belongs to a promise.
This means it won't be executed immediately, but later in the angular life cycle.
Your console.log() will always log 'undefined' because your variable won't be initialized there.
You can try this to log the value:
$scope.$watch(
function() { return contentOwnerId; },
function(newContentOwnerId, oldContentOwnerId) {
console.log(newContentOwnerId);
}
);

Create variable to JavaScript array from another function?

I have a function that create and store an array for all the p elements:
function dummyArray(){
var $dummy= $('p');
var dummy= [];
i = 0;
$dummy.each(function()
{
dummy[i++] =$(this).html();
});
return dummy;
}
Now, in order to reuse the array in another function, I can use dummyArray() and dummyArray()[0] to access the individual data.
function initAll(){
//dummyArray();
//dummyArray()[0];
}
However I want to store it inside a variable like below but it gives me error.
function initAll(){
var allArray = dummyArray();//error
}
Is there a way to store it inside a variable or is there a better way of doing this?
After cleaning up my code I noticed that using var allArray = dummyArray(); does work, the error was generated from something else. cheers~
Edited:
The error I found out was the function name cannot be the same as the new variable name declared even though the () aren't there.
var dummyArray = dummyArray();//error
var allArray = dummyArray();//works

Categories

Resources