javascript function returning issue - javascript

I want to return the var "source" value for all the element, now when I put the "source" out of each function, it become undefined.I want to return the whole source array. How to do that? any help would be truly appreciated -
function _getSource(){
var product = fpd.getProduct(true);
$(product[0].elements).each(function(i, elem) {
var source = elem.parameters['source'];
})
return source;
alert (source);
}

Assuming that you're actually after an array containing the source property of each element:
function _getSource(){
var product = fpd.getProduct(true);
return $(product[0].elements).map(function(i, elem) {
return elem.parameters['source'];
}).get(); // .get() turns jQuery collection into an array
}
.map is a very good replacement for a .each / push combo. It comes from functional languages where the "map" function just takes an array, transmutes each elements, and returns a new array of those transmuted results.
The final .get is not strictly necessary if you don't mind getting an array-like result back rather than a proper array.

When you write var source you are declaring a new variable scoped to the function of the each callback. Declare it outside and get rid of the var so you are just assigning instead of redeclaring, and you probably also want to build up an array and not just assign. Something like this:
function _getSource(){
var product = fpd.getProduct(true);
var sources = [];
$(product[0].elements).each(function() {
sources.push(elem.parameters['source']);
})
return sources;
}

source is only defined inside the each function because you var'd it there.
Try this instead:
function _getSource() {
return $(fpd.getProduct(true)[0].elements).map(function() {return this.parameters['source'];});
}

Related

Create javascript object dynamic in a foreach loop

I want to create objects in a foreach loop:
I'm starting from this:
data.forEach(function (el) {
var dynamic_var = new Quill(el['editor']);
dynamic_var.on('text-change', logHtmlContent);})
But, dynamic_var is 'overwritten', and I want to remain unique.
I check some html elements, and for each one that I found I want to create a new Object, and execute the Object methods.
In my case the variable get a new object per each iteration, is not a new variable.
Is this what you were looking for?
var quillValueContainer = {};
// ...
data.forEach(function(el) {
quillValueContainer[el] = new Quill(el['editor']);
quillValueContainer[el].on('text-change', logHtmlContent);
});
This will only work if el is a string, or number. Seeing how you are using it like this: el['editor'], makes me thing it's an Object, in which case, you can instead use the indices of the elements.
var quillValueContainer = {}; // [] should also work for indexes
// ...
data.forEach(function(el, index) {
quillValueContainer[index] = new Quill(el['editor']);
quillValueContainer[index].on('text-change', logHtmlContent);
});
Also, I don't know if this is something you need to do, but you can check if the Quill Object has already been initialized and skipping a duplication if it has, by doing:
data.filter(function(el, index){ return !quillValueContainer[index]; }).foreach(...
Or
data.forEach(function(el, index) {
if(quillValueContainer[index]) return;
quillValueContainer[index] = new Quill(el['editor']);
quillValueContainer[index].on('text-change', logHtmlContent);
});

Why does array contain only last value n times?

This function returns the same value in the array list.
For example if i=10, then my array should contain 10 different values, but it stores only the last value 10 times.
What is the problem in my code?
$scope.webTempIds=[];
$scope.wId={};
$scope.getIds=function(){
for(var i=0;i<$rootScope.retData.length;i++){
$scope.wId.ID=$rootScope.retData[i].WEBUI_TEMP_ID;
$scope.webTempIds.push($scope.wId);
}
return $scope.webTempIds;
}
$scope.wId={};
is changed every time. The array contains the reference to this object and hence when you change the value it changes the value in the array.
let obj = {};
let result = [];
for(let i = 0; i<10; i++){
obj.a = i;
result.push(obj);
}
console.log(result);
This happens because you use $scope for wId.ID outside of loop. Therefore your list items point to the same object.
Once you change $scope.wId.ID , the list $scope.webTempIds will be updated too.
To fix it make id local:
for(var i=0;i<$rootScope.retData.length;i++){
var wId = {
ID: $rootScope.retData[i].WEBUI_TEMP_ID;
}
$scope.webTempIds.push(wId);
}
As a side note: use Scope to bind application controller and the view. (inside the for loop you don't need scope)
As others have correctly pointed out, you end up with the last item in the array because the value that you push to the array is on the $scope and gets replaced with the new value each time.
To offer an alternative approach, you could use the Array.prototype.map function to return a new array prepopulated with just the id property values of each data item:
$scope.getIds=function(){
$scope.webTempIds = $rootScope.retData.map(
function(obj){
return obj.id;
}
);
}
This eliminates the need for any loops with temporary variables and any pushing to manually build up a new array from scratch.
$scope.getIds=function(){
$scope.webTempIds=[];
for(var i=0;i<$rootScope.retData.length;i++){
$scope.wId={};
$scope.wId.ID =$rootScope.retData[i].WEBUI_TEMP_ID;
$scope.webTempIds.push($scope.wId);
}
return $scope.webTempIds;
}

Adding values to a specific property in an array(?) in javascript

Im wondering how I can add a value to to main in this array.
var herpderp = {
"main": ["stuff", "stuff"]
};
so it would look like:
var herpderp = {
"main": ["stuff1", "stuff2", "stuff3"]
};
Preferably I'd like to create this kind of structure from a couple of strings in a fucntion if that's possible. So says I have this
var strings = {"stuff1","stuff2", "stuff3"}
for (each element of strings) {
what do I do here to get the structure above
}
Alternatively another function to search through an Array of objects on a specifik property. Right now Im trying to use this to filter through the array, maybe there's another way?
var arrays = search;
var result = events.filter(function(item) {
for (var prop in arrays)
if (arrays[prop].indexOf(item[prop]) == -1)
return false;
return true;
});
Thank you kindly for any reply!
herpderp.main is your array, so you can add to the array like so:
herpderp.main.push(value)
If the key for your array was not a valid variable name (it starts with a number, for example), you could use bracket notation instead:
herpderp['123key'].push(value)
Actually, you are changing the previous values beside adding a new element.
var herpderp = {
"main": ["stuff", "stuff"]
};
var strings = ["stuff1","stuff2", "stuff3"];
strings.forEach(function(value,key){
herpderp.main[key] = value;
});
console.log(herpderp);

How to create array with variables?

I have an svg map with several points where I want to store the initial position of each point in an array. And each point has it's own ID, like point_1, point_2 etc.
I have attached a click handler to each of these and run a function when they are clicked.
So what I want to do in this function is to check if the array already contains the information of the clicked element. If it doesn't, I want to create it.
This is what I want to do, in pseudo code
var arrPoints = [];
zoomToPoint('point_1');
function zoomToPoint(data_id) {
// Does array already contain the data?
if (!arrPoints.data_id) {
// Add data to the array
arrPoints.data_id.clientX = somevalue;
arrPoints.data_id.clientY = somevalue;
}
}
This would basically create an array that looks like this:
arrPoints.point_1[]
arrPoints.point_2[]
Where I can access the data in each .point_1 and .point_2.
But I can't create an array based on a variable, like this:
arrPoints.data_id = [];
Because I end up with data_id as the actual name, not the variable that data_id actually is. So how is this usually accomplished? How can I identify each point to the actual array?
Sorry for my lack of basics
Just use an object:
var arrPoints = {};
zoomToPoint('point_1');
function zoomToPoint(data_id) {
// Does array already contain the data?
if (!arrPoints[data_id]) { // square brackets to use `data_id` as index
// Add data to the array
arrPoints[data_id] = {};
arrPoints[data_id].clientX = somevalue;
arrPoints[data_id].clientY = somevalue;
}
}

putting source of all images into an array

What is the cleanest way to put the source attribute string of all images within a div into an array?
I was hoping this would work -
var imageSourceArray = $("#leDiv img").attr('src');
alert(imageSourceArray[3]); //not alerting the source, boo hoo.
Do I need to loop through $("#leDiv img") and add each src string to an array individually? Or is there a more elegant way to do this?
You can use jQuery's map function which is described as:
Pass each element in the current matched set through a function, producing a new jQuery object containing the return values.
For your example:
var mySources = $('#leDiv img').map(function() {
return $(this).attr('src');
}).get();
Edit: Far more elegant solution, there's obviously still some looping involved internally:
var img_sources = $('#leDiv img').map(function(){ return $(this).attr('src') });
You will in fact need to loop over the collection and add sources individually.
var img_sources = [];
$('#leDiv img').each(function(i,e){
img_sources.push($(e).attr('src'))
})
Some background: jQuery.fn.attr() maps to jQuery.access() internally, the key part of which looks like this:
function( elems, key, value, exec, fn, pass ) {
var length = elems.length;
// setter functions omitted here …
// Getting an attribute
return length ? fn( elems[0], key ) : undefined;
}
Note the elems[0] part – only the first item in the collection is fed to the subsequent callback function (jQuery.attr() in fact) responsible for extracting the information.
var imageSourceArray = [];
$('#leDiv img').each(function(){
var src = $(this).attr("src");
imageSourceArray.push(src);
});
alert(imageSourceArray[3]);
you already have the src in a collection when you fetch the the images. It may be more efficient to not store the src attributes in another array:
$('#leDiv img').each(function(i,e){
var dosomethingwith = $(e).attr('src');
})
or you could do:
var ImageCol = $('#leDiv img');
alert(ImageCol[3].attr('src'));

Categories