I am using ReactJS.
I have a JSON:
{
"randomNum1": [
1,
2,
3,
4
],
"randomNum2": [
5,
6,
7,
8
]
}
What I wanted to do is to get the array of randomNum1 and randomNum2. This is what I did:
for(let i = 0; i<data.randomNum1.length; i++)
and I get this error:
Cannot read property 'length' of undefined
The reason why I did that is because when I do a console.log(data.randomNum1) I am able to see the array: [array][1]
Is it because it's still an Object which is why .length is not allowed? If so, how can I get the values of those numbers and store it in an array?
[1]: https://i.stack.imgur.com/nLbdA.png
let allValues=[]
let the_json_object={
"randomNum1": [
1,
2,
3,
4
],
"randomNum2": [
5,
6,
7,
8
]
}
const keys = Object.keys(the_json_object);
const values = Object.values(the_json_object);
let Key_len = keys.length;
for(i=0;i<Key_len;i++){
let len = values[i].length;
for(j=0;j<len;j++)
{
if(values[i][j])
{
allValues.push(values[i][j])
}
}
}
//allValues contains all the values from all arrays.
Your data object is probably undefined at the moment you are entering the loop.
The reason you see it on console.log is because objects are passed by reference. When you console.log the object and then click to see his properties you get the updated object. If you'll do console.log(JSON.stringify(data)) you will see the object is probably empty.
Please provide more code in order to understand the issue here.
Related
I have a weird problem that I can't solve since yesterday on Garry's Mod (GLua)
When my gmod server game is running, I notice that there are errors on arrays that are empty with certain keys when they are well specified, while doing deep tests, I noticed that the returned arrays were ... backwards.
Here is an array below:
bigArray = {
[ "default" ] = { 4, 2, 1 },
[ "police" ] = { 4, 2, 1 },
[ "mayor" ] = { 5, 2, 1 },
[ "sherif" ] = { 6, 2, 1 },
}
Good, next I will use the PrintTable() method (PrintTable() is a method already integrated in the game) which displays the contents of an array (This method, normally if I run PrintTable(bigArray) the result should be literally the array above, but here is the result displayed:
{
[ "sherif" ] = { 6, 2, 1 },
[ "mayor" ] = { 5, 2, 1 },
[ "police" ] = { 4, 2, 1 },
[ "default" ] = { 4, 2, 1 },
}
I will put an example more telling since the previous one is an dictionary and not really an array :
table = {
'truc',
'machin',
'chose'
}
If I display the first element of the table like this print(table[1]), the displayed result will be: chose
Flipping the tables upside down makes a lot of addons I use crash, I have no idea how this happened, it happened suddenly without me modifying any addon (I already looked at the worshop addons, none of them are responsible for the problem)
If someone has an idea how this could be caused, I'm interested, thanks.
Edit :
I installed my project on a virtual machine, and when I launched the server, I had none of the errors I mentioned.
I formatted my entire machine containing the errors and since then the problem is solved.
Following this observation, I still think that the problem did not come from the code, maybe my assembler or the game was corrupted, who knows.
Thanks for those who tried to answer my problem, and if someone one day encounters the same problem, I strongly advise him to check the integrity of their game.
I noticed that the returned arrays were ... backwards
They are not arrays. They are dictionaries (unordered set of key-value pairs).
An array in Lua would look like the following:
bigArray = {
{ name="default", 4, 2, 1 },
{ name="police", 4, 2, 1 },
{ name="mayor", 5, 2, 1 },
{ name="sherif", 6, 2, 1 },
}
In this case order of elements is preserved:
$ lua
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> bigArray = {
{ name="default", 4, 2, 1 },
{ name="police", 4, 2, 1 },
{ name="mayor", 5, 2, 1 },
{ name="sherif", 6, 2, 1 },
}
> bigArray[1].name # This will _always_ be "default"
default
In Garry's Mod dictionaries are not stored in any particular order. If you want to iterate through a dictionary in order, rather than using pairs you must use either SortedPairs, SortedPairsByMemberValue or SortedPairsByValue.
See this wiki page for reference.
For your implementation, I would recommend adding a field to each member value of your bigArray dictionary to specify a sort order; for instance:
local bigArray = {
[ "default" ] = {
sortOrder = 1,
myValues = { 4, 2, 1 }
},
[ "police" ] = {
sortOrder = 2,
myValues = { 4, 2, 1 }
},
[ "mayor" ] = {
sortOrder = 3,
myValues = { 5, 2, 1 }
},
[ "sherif" ] = {
sortOrder = 4,
myValues = { 6, 2, 1 }
}
}
This would then allow you to iterate in order of the sortOrder value, like so:
for key, value in SortedPairsByMemberValue(bigArray, "sortOrder") do
print("\n" .. key .. ":")
PrintTable(value)
end
you need to add new values to the array, I can't understand what the problem is.
When you click on a checkbox, you need to get the id of this checkbox and write it to the array of answers for the corresponding question
type Result = number;
interface Answer {
result: Result[];
}
const answers: Answer[] = [];
questions.forEach(() => {
answers.push({
result: [],
});
});
const [currentAnswer, setNewAnswer] = useState<Answer[]>(answers)
const handleChange = (e:React.ChangeEvent<HTMLInputElement>) =>{
// console.log(typeof(currentAnswer),currentAnswer);
if(e.target.checked){
console.log(currentAnswer[currentQuestion].result.push(Number(e.target.id)));
setNewAnswer(
currentAnswer[currentQuestion].result.push(Number(e.target.id) // ERROR HERE
)
...
I got error
const currentAnswer: Answer[]
// Argument of type 'number' is not assignable to parameter of type 'SetStateAction<Answer[]>'
should use .concat() in this situation to return new array
.push() will only return new length which is number and incompatible with the type you make.
setNewAnswer(
currentAnswer[currentQuestion].result.concat(Number(e.target.id)) // ERROR HERE
)
To expand on Mic Fung's answer, push mutates the existing array and doesn't return the new array.
const myArray = [1, 2, 3]
myArray.push(4) // returns 4, which is the new array length
console.log(myArray) // [1, 2, 3, 4]
concat doesn't mutate the existing array, but instead returns a new array
const myArray = [1, 2, 3]
const myNewArray = myArray.concat(4)
console.log(myNewArray) // [1, 2, 3, 4]
console.log(myArray) // [1, 2, 3]
When working with React, you should avoid directly mutating the state. Instead, create new values and pass them to the setState function. This is why functions like concat are preferred over ones like push, as they avoid the mutation.
I'm trying to search a element in the array. When get it i need to append some element of the end of the array.
I try similar to this.
List dataModelo = allMakers //THIS IS THE MAIN ARRRAY
.where((modelo) =>
modelo["fabricante"] ==
fabricante["fabricante"])
.toList()
.addAll([
{
"id": 0,
"fabricante":
'Test,
"modelo":
'Test'
}
]);
But return
The expression here has a type of 'void', and therefore cannot be
used.
So anybody know how can i do that?
SOLUTION:
dataModelo = allMakers
.where((modelo) =>
modelo["fabricante"] ==
fabricante["fabricante"])
.followedBy([
{
"id": 0,
"fabricante":
'TEXT',
"modelo":
'TEXT'
}
]).toList();
Use cascade notation after the .where(/**/).toList() part.
e.g.
final arr = [1, 2, 3];
print(arr.where((a) => a > 2).toList()
..addAll([ 4, 5 ])); // returns [3, 4, 5]
In other words, adding another . to your .addAll part should do the trick.
I stuck with this bit and I can't progress - I guess solution is simple but I can't figure out. I'm trying to add entry in reducer so data in in would look something this:
state = {
entryId: {
entryName: ["something", "something2", "something3" /* and so on... */]
}
};
So far this is the closest I get, but, instead of adding new unique entry, it is replacing the one that is stored already. Also I need to be able to add this item to empty state where entryId, entryName doesn't exist yet to avoid error:
switch(type) {
case ADD_ENTRY:
return {
...state,
[entryId]: {
...state[entryId],
[entryName]: {
[uniqueEntry]: true
}
}
};
}
Any idea what I'm doing wrong?
If you're trying to add an element to the end of the entryName array you should be doing:
return {
...state,
[entryId]: {
...state[entryId],
[entryName]: [
...state[entryId][entryName],
uniqueEntry
]
}
};
ES6 spread with arrays works like this:
const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const eight = 8;
const newArray = ['stuff', ...array1, 'things', ...array2, ...[7, eight], 9];
console.log(newArray); // ["stuff", 1, 2, 3, "things", 4, 5, 6, 7, 8, 9]
Check out this gist which has an example of something very similar to what you're doing.
I found this set of examples extremely helpful as well. A lot of great stuff in here:
https://github.com/sebmarkbage/ecmascript-rest-spread
Update:
If entryName is initialized to undefined like you say in your comment, you could do this:
return {
...state,
[entryId]: {
...state[entryId],
[entryName]: [
...state[entryId][entryName] || [],
uniqueEntry
]
}
};
I think this is a pretty great example of how painful it can be working with React/redux using a heavily nested data structure. FWIW, it's been recommended to me many times to flatten your state as much as possible.
I am having this format in my script
//declaration of JSON object
items= {};
items.values= [];
I need a structure like this, which is inserted automatically when the script is executed:
items :
{
key :['one', 'two', 'three', 'four'],
values: [1, 2, 3, 4]
}
Since the item.values[0] is undefined, it throws me a undefined error. Can anyone please tell me how to initialize the JSON object, such that it wont throw undefined error
I would like to insert like this:
var i=0;
item.key[i]= 'one';
item.values[i]= 1;
I am not sure whether this is the best practice, if anyone knows better way please post it!
Thanks in advance
You have the right idea. It looks like your property for adding keys isn't there though. Let's declare two properties, keys and values.
items= {};
items.keys = [];
items.values= [];
Our JavaScript object now looks like this
{ "keys": [], "values": [] }
var words = ['one', 'two', 'three', 'four'];
var numbers = [1,2,3,4];
You now want to iterate using a forloop. In JavaScript, arrays are 0-indexed, meaning the first element has an index of 0. That's why we initialize the i variable with a value of 0. After every iteration, we increment this variable and then check if it's less than the length of the array.
function populateObject() {
for (var i = 0; i < words.length; i++) {
items.keys.push(words[i]);
items.values.push(numbers[i]);
}
}
And then call your function
populateObject();
Here is the output
{"keys": ["one", "two", "three", "four"], "values": [1, 2, 3, 4]}