jqGrid('getGridParam','colNames') odd behavior - javascript

Using this function to return the column names of the grid works fine. The issue comes when splicing the array that it returns.
The grid includes a checkbox as the first column so I want to remove that from the array. Here is that code.
var columnTitles = $(table).getGridParam('colNames');
columnTitles.splice(0,1);
The problem comes when I use this function multiple times (it's exporting to excel). The next time I export, the getGridParam function actually returns the spliced array of column names rather than the actual ones. It's as if it's being passed by reference or something.
Further proof that it's doing that and I don't just have a problem with a global variable or something...if I do the following code:
var columnTitles = $(table).getGridParam('colNames');
var columnTitles2 = $(table).getGridParam('colNames');
columnTitles.splice(0,1);
console.log(columnTitles2);
The value of columnTitles2 comes back as the spliced array. It might be something completely stupid, but what am I missing here?

The method getGridParam returns the reference of internal parameters used by jqGrid. You should be careful if you work with arrays or objects, colNames or colNames for example. It you need to modify the arrays for your purpose, but you don't want to change the values in jqGrid you should first make copy of the arrays and then modifies the copy:
var columnTitles = $(table).jqGrid("getGridParam", "colNames").slice();
columnTitles.splice(0,1);
I used slice to make the copy of internal colNames used by jqGrid.

Related

strange javascript variable re assignment issue

I have a variable called data, which brings an array to a function.
I then decided to continue using only the first element of the array (data[0]). would it have any difference if I do either of the following?
reuse/replace the array variable name data by assigning it with its first element, which would be
data = data[0]
and continue to use data
declare a new variable and assign it the first element of the array data, which would be
var data_new = data[0]
Is there any problem in doing the first one? is there any case that I should strictly use the second one instead of the first one?
I am asking this because I had a strange problem related to this, when I got a data from a fetch request and it made a difference when I used the first method and the second method.
fetch("some json array returning url").then(response=>{
response.json().then(data => {
data = data[0]
setState(data);
return;
// Vs
var data2 = data[0]
setState(data2);
return;
//based on which is uncommented
}
}
On my first block (using same variable data), the result was randomly changing. but when I used the second block, It became stable and predictable.
To be more specific on the results, for data that as the form ["data"], when using the first block, the result fluctuates between "data" and "d", where as while using the second block, it always returns "data"
Sorry for I can't put a fully reproducible example, But It would really help me out if there is any possible reason to prefer one over the other according to javascript language, based on the above simple use cases.
Usually, you don't want to be mutating the parameters of a function. Doing data = data[0] may cause bugs later on. It is better to create a new variable and make changes to that one, as with var data2 = data[0].
I don't see any problems with both of them, but in the 1st method it can make code more confusing to read because the variables have different types in different places. I would prefer solution 2

Access Array with String key

I have two variables with JSON files. The first is a list of keys looks like this:
keylist = ["key1","key2","key3"]
The second one is generated from a database and looks like this:
data = {
"key1"{
#further data
},
"key2"{
#further data
},
"key3"{
#further data
}
}
Now I want to access the second element of the database with the key from the keylist
data.keylist[1];
Which doesn't work because the return of keylist[1] is a String? I did some research and the use of the window function was proposed. So I tried this:
window["data." + keylist[1]]();
Which leads to a "is not a function" error. What can I do to solve this problem?
As simple as that:
const mydata = data[ keylist[1] ];
Also, your code is correct from the point of syntax, but it tells completely different than you expect it to tell.
data.keylist[1];
tells JS that you expect to have an object called data which has a property called keylist and which is (most likely) type of array, and you want to get the second element of this array.
PS: And one more point here. Your question title is not completely correct because of the difference between Arrays and Object in JS.
There is no "string keys" for arrays in JS, so you cannot "access array with a string key". Well, truly speaking there are, but not for items of array. Array items only have numeric index, which you can use to access it. Objects, in contrast to arrays, may have named properties. So when you see something like that: data = myVar['data'], you can tell that you're dealing with an object, while data = someVar[0] can be both, an Array (most likely) or also an Object with key named '0'.
I don't think the issue you're having with your first example is because it returns a key. I believe the issue is because data doesn't have a property called keylist. Instead of that, try it as
data[keylist[1]]
and see if that works for you. The reason this one should work is that, in this situation, Javascript will evaluate the string return of keylist[1] and then use it as a string index for the data variable. Let me know if this works out for you :D
You can try using using something like this.
data[keylist[1]]

Sorting using nested field in ramda.js

In the documentation of sortBy, it says we can use R.prop to sort an object by it's field. But if I have to sort by a nested field, it does not work. For example R.prop('id.number') does not work.
var items = [{id:3},{id:1},{id:2}];
var sorter = R.sortBy(R.prop('id'));
sorter(items)
works fine. But if I have a nested structure
var items = [{id:{number:3}},{id:{number:1}},{id:{number:2}}];
var sorter = R.sortBy(R.prop('id.number'));
sorter(items)
returns me an empty list. I guess there is a correct way of using R.prop that I am not able to figure out.
You can use R.path for accessing nested properties, so your example would become R.sortBy(R.path(['id', 'number']))
Unless I'm mistaken, id.number itself is being checked as a property, when in fact there is only the property id. R.prop() only checks one level down - nested structures are beyond its ability, and being asked to look for the property number after doesn't work .
The documentation states that sortBy accepts a function which takes an element under consideration. The following is tested on the ramda.js REPL and works:
var items = [{id:{number:3}},{id:{number:1}},{id:{number:2}}];
var sorter = R.sortBy(function(item) {return item['id']['number'];});
sorter(items)
It works by simply looking up the properties in succession.
tl;dr Anonymous functions for the win.

Javascript object changing everywhere, if I change somewhere

I've one object, where one value is array of numbers and I call two functions, first function sorts data and display it, second function just display it.
problem is that, in second function, data is also sorted. (I'm not sorting there, data have come already sorted)
function1(data);
function2(data);
How can I fix it?
One simple solution to this would be create a copy of the object and then using it.
You can create a copy of the object, if don't want that using:
b = Object.create(a)
In this case b is a copy of a but if you make changes in a, it won't reflect in b. For more info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
Reason: In javascript objects are passed by reference
http://www.w3schools.com/js/js_function_parameters.asp
Create clone inside sorted function before sorting it
Try like this
var cloneData=data.slice();
your function1 is sorting the data which means the data will be sorted when you call function2, what you can do is in function1 take in data, but create a new variable from data and then update that so the original data is never changed
However displaying some code for function1 and function2 would really help us provide some useful code :)
You will need to duplicate your object to do this. It has to do with object refencing and such.
VERY short explanation (way too short to do it any justice) is that function1 and function2 are using the same array, so when function1 changes it, this is visible in function2 afterwards. read up in this question here, this is definitely something you should research as a programmer.
var data = ['b', 'c', 'a'];
var sortedData = data.slice(0); // shallow copy, objects in the array are not copied
call the function that sorts with sortedData, call the function that only displays with data
Read up more about object references and primitive values to understand how changing values in one array is going to affect to other one, but if you aren't changing the values anymore this is not an issue you need to worry about.

Function param array, how to affect reference = [] or reference.concat(array2)? [duplicate]

This question already has an answer here:
Mutate JavaScript Array Inside Function
(1 answer)
Closed 8 years ago.
So it could just be I'm crazy tired but I can't seem to figure this out.
I've been picking up javascript which I'm finding horrible coming from actionscript 3 where everything was typed. I had a function that referenced two array variables directly, I later needed to use it again for a different data set so I've altered it to take parameters and now it's breaking.
I have one array full of elements, the 2nd is empty. When I call the function, a random element is removed from the first array and pushed into the 2nd array, that element is also returned by the function. If the 1st array is empty I have concat the 2nd array to fill it back up. The goal was to randomly iterate through the elements and not have the selected elements show up again until I had finished a full cycle.
Prior to concat I was using slice(which should work just as well?), the problem I believe is that I know have a parameter that is redefined when I do 'array = array2.slice()', concat doesn't seem to work around that. I don't know if returning the single sliced element from the first array is bad if I'm expecting a string, I think slice is returning an array with the single element, easy fix there though by adding [0] to the return statement.
Heres the code:
//Gets a random element from array, that element is moved from the 'src' array to the 'bin' array,
//this allows random selection without choosing the same element until all of 'src' array elements have been picked
function getRandomElement(array_src,array_bin){
//Randomly selects a tweet from the que, then stores it in another array so each tweet shows once before recycling
if(array_src.length==0 && array_bin.length>0) {array_src.concat(array_bin);} //Recycles array elements when the src array is empty
var randomElement = array_src.splice(Math.floor(Math.random()*array_src.length),1); //Grab a random array element
array_bin.push(randomElement);//array elements stored here to be recycled
return randomElement;
}
I think I could maybe use an object with two properties pointing to the arrays and pass those in, though it'd be nicer if there is a better way. I could also use push on array_src looping through the array_bin to work around that issue if there isn't any other way.
I wouldn't say this is a duplicate Felix. The answer you provided is pretty much the same, but the question itself is phrased differently, I wasn't aware of the term mutate, finding the question/answer wouldn't be easy, none of the suggested links SO provided were relevant. Worth keeping up for making the answer more discoverable to those unaware of the mutate term.
I have a hard time understanding the problem, but I think you are wondering why array_src.concat(array_bin) doesn't seem to do anything?
That's because .concat returns a new array. If you want to mutate the existing array_src array, you can use .push:
array_src.push.apply(array_src, array_bin);
FWIW, this has nothing to do with strong typing. JavaScript (and I guess ActionScript as well), is pass-by-value. That implies that assigning a new value to array_src doesn't change the value of the variable that was passed to getRandomElement.
But since arrays are mutable in JavaScript (and ActionScript I assume), you can mutate the array itself.

Categories