unable to push and append data to the state using React js - javascript

here i state with data
state = {
Response: [
{
"id": "15071",
"name": "John",
"salary": "53",
"age": "23",
"department": "admin"
},
{
"id": "15072",
"name": "maxr",
"salary": "53",
"age": "23",
"department": "admin"
},
{
"id": "15073",
"name": "Josef",
"salary": "53",
"age": "23",
"department": "admin"
},
{
"id": "15074",
"name": "Ye",
"salary": "53",
"age": "23",
"department": "admin"
}
]
i am displaying these records in the table. In table u will see 10 records and there will be a button on top of table so if append button is pressed then 10 records has to be added on every button press and the data has to be same but it has to be appended using the below logic i am trying to set the state by pushing 10 records and trying to append it for ex if i have 1,2,3,4,5,6,7,8,9,10 if i press append 1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10 has to be apeended
appendEmployees() {
var reLoadCount = 1;
for (let i = 0; i < 10; i++) {
const myObj = {
id: 0,
name: '',
salary: 0,
department: ''
};
myObj.id = +this.setState.employee[i].id + (reLoadCount * 10);
myObj.name = this.setState.employee[i].name;
myObj.salary = this.setState.employee[i].salary;
myObj.department = this.setState.employee[i].department;
this.setState.employee.push(myObj);
}
reLoadCount++;
}
am i doing some thing wrong here

If I get this right you're trying to add 10 duplicates of the objects in the this.state.employee array, the only difference between these new objects and the existing ones is their id.
If that is the case, here is how you can do that:
appendEmployees() {
this.setState(prevState => {
// Get the biggest ID number.
const maxId = Math.max(...prevState.employee.map(e => parseInt(e.id)));
// create 10 new employees copies of the first 10.
const newEmployees = prevState.employee.slice(0, 10).map((e, i) => ({
...e,
id: (maxId + i + 1)
}));
// return/update the state with a new array for "employee" that is a concatenation of the old array and the array of the 10 new ones.
return {
employee: [...prevState.employee, ...newEmployees]
}
});
}
I've added some comments to the example to explain what it does.
The important thing is this.setState which is the function used to update the state, here, I've used it with a function as the first parameter (it works with objects as well), I've did that because it is the preferred way of generating a new state that is derived from the old state.

Related

Return Javascript child array based on parent filter

Disclaimer: I know some Java but almost nothing about Javascript and have about 2 days to fix someone else's issues, of which this is one small part.
I have a nested array. I know the shop number, but need to get an array of only the parts in that shop.
"shops": [
{
"shopID": "15231",
"city": "Anytown",
"state": "MO",
"inventory": [
{
"description": "filter",
"partnumber": "MGL57047",
"shelf": "Z",
},
{
"description": "filter",
"partnumber": "84060",
"shelf": "A",
}
},
{
"shopID": "15232",
"city": "Springfield",
"state": "IL",
"inventory": [
{
"description": "filter",
"partnumber": "MGL57048",
"shelf": "B",
},
{
"description": "filter",
"partnumber": "84061",
"shelf": "A",
}
}
Here's what I tried:
const enteredShopID = '15231' // This isn't hard-coded in my app.
// Pull the list of all consumables for the current shop
var currentShop = application.data.shops.filter(s => s.shopID == enteredShopID)
This gets me an array with the shop and all of the inventory for that shop, but I need an array of the inventory. I tried
var currentShop = application.data.shops.inventory.filter(s => s.shopID == enteredShopID)
but that didn't work. Really, I'm just fumbling here. Is there a way to make the latter statement work, and somehow refer to the shopID of the parent?
Just use map() after the filter.
var currentShop = application.data.shops
.filter(s => s.shopID == enteredShopID)[0]
// checking if the current shop is actually null because no shops matched the ID
var currentShopInventory = (currentShop || {}).inventory || []
or use find()
// Note: If you use find(), there's a chance that there is no matching object
// So you'll have to check for that before you access the "inventory" key
// Otherwise you'll get "Cannot access 'inventory' of null"
var matchingShop = application.data.shops
.find(s => s.shopID == enteredShopID)
// Doing the checking here using an "or" if the matchingShop is null
var currentShop = matchingShop || {}
var currentShopInventory = currentShop.inventory || []

JS - copy object from an array to the new one when the condition is met [edited]

What I have to do is filter the array and write selected elements in the new one. Previously I saw two possible ways, but thanks to comments bellow I realised that way with deleting elements from array is not good. So what I need to do is to copy some elements (i.e. everything with category "science") to new one. My first question is: which approach is better? more efficient? Thank you for your help!
Now second question. How can I copy elements from my array to the new one? It was not a problem to copy only a book name form element with id 0. But when I was trying to copy id, name, category, price and image is exactly the same form to the new array the attempt failed...
My array is:
var products =
[
{
"id": "0",
"name": "Book Name",
"category": "science",
"price": "$49,99",
"image": "img/product-1.png"
},
{
"id": "1",
"name": "Book Name 2",
"category": "computers",
"price": "$319",
"image": "img/product-2.png"
},
{
"id": "2",
"name": "Book Name 3",
"category": ["science", "programming", "computers"],
"price": "$49,99",
"image": "img/product-1.png"
}
]
below I tried to remove mismatched elements, but this approach turned out to be less effective and more problematic.
let checkedOperations = 'programming';
let selected_products = [... products];
$(document).ready(function () {
for (var i in products) {
if (isTrue(checkedOperations, products[i].category)) {
selected_products.splice(i,1);
}
console.log('selected products after slice -1 = ' + selected_products[1].name);
console.log('selected products after slice = ' + selected_products[2].name);
console.log('selected products after slice +1 = ' + selected_products[3].name);
}
});
Using forEach should do the trick without handling indexes and thus making it less error-prone.
let resArray = []; // Filtered result array
products.forEach((el) => {
if (el.id === "0") { // Whatever condition you want
resArray.push(el);
}
})

findIndex() returns as -1 and not correct index number

Struggling with this one. It was working before and not sure, why it is not now...
I have a ToDo app, containing a form, with two inputs - one for name. And one for url.
I should be able to edit any input value. And then save/update the updated array object, in local storage.
If I click on my edit button, without changing an input value, the correct index number is returned, (0 or 1).
But if I change an input value. And THEN click the edit value, -1 is returned.
And therefore, the rest of my function does not work, as my JS is not finding the correct index to update, the object with.
Here's a snippet of the code. What am I doing wrong?
bookmarksArray: [
{
"name": "jane",
"url": "http://www.jane.co.uk/"
},
{
"name": "mark",
"url": "http://www.google.com"
}
]
// UPDATE/EDIT EXISTING BOOKMARK
list.addEventListener('click', event => {
if (event.target.classList.contains('js-edit-url')) {
const editName = event.target.parentElement.name.value;
const editURL = event.target.parentElement.url.value;
let constUpdatedOBj = {name: editName, url: editURL};
const objIndex = bookMarksArray.findIndex(obj => obj.name === editName);
console.log('editName', editName);
console.log('editURL', editURL);
console.log('objIndex', objIndex);
bookMarksArray[objIndex] = constUpdatedOBj;
window.localStorage.setItem("bookMarksArray", JSON.stringify(bookMarksArray));
}
});
This is working as I would expect it to, if you start out with your array like so:
bookmarksArray: [
{
"name": "jane",
"url": "http://www.jane.co.uk/"
},
{
"name": "mark",
"url": "http://www.google.com"
}
];
And then the name mark is edited in the input to tony, this is essentially what you're getting:
const objIndex = bookMarksArray.findIndex(obj => obj.name === 'tony');
"tony" doesn't exist in the bookmarksArray so findIndex is going to return a -1.
What you need is an id on those bookmarks:
bookmarksArray: [
{
"id": 1,
"name": "jane",
"url": "http://www.jane.co.uk/"
},
{
"id": 2,
"name": "mark",
"url": "http://www.google.com"
}
];
And then have your findIndex look for the correct record based on the id:
const bookmarkId = event.target.parentElement.id.value;
const objIndex = bookMarksArray.findIndex(obj => obj.id === bookmarkId);

Javascript loop over object and create missing objects from array

I have an object of data that is loaded from a database. A user can select options on the page and for each of those options that don't exist in the initial object, I need to create them.
I wrote up some psuedo code for what I am attempting here, its causing a memory issue though and crashing.
The goal here is that I iterate over each task > Roles array and check to see if theres any missing objects that need to be created. The object that need to be created come from selectedRoles.
Desired Outcome:
In the first task, it should create 3 roles as its currently empty. In the second task, it would create roles 1 and 3 because a role with the id of 2 already exists.
var tasks = [{
"User": {
"FirstName": "Joe",
"LastName": "Dirt",
"selected": false,
"marked": false
},
"Tool": {
"id": 31,
"text": "Admin",
"ToolID": "31",
"ToolName": "Admin",
"ToolSuite": "Enterprise Product"
},
"Roles": []
}, {
"User": {
"FirstName": "Bart",
"LastName": "Simpson",
"selected": false,
"marked": false
},
"Tool": {
"id": 35,
"text": "Wordpress",
"ToolID": "35",
"ToolName": "Wordpress",
"ToolSuite": "Enterprise Product"
},
"Roles": [{
RoleName: 'Role 2',
Role: 2,
RoleID: 2
}]
}];
// New selected roles from list
var selectedRoles = [1, 2, 3];
////////////////////////////////////////////////////////////////////////
/*
Loop over the configured tasks and
if there is not an existing role
matching a role id from "SelectedRoles",
create a new role within that task.
*/
// Loop over the tasks
tasks.forEach((task) => {
// If we have roles, loop over them
if (task.Roles.length) {
for (let i = 0; i < task.Roles.length; i++) {
// If this roleID does not exist in our selectedRoles, create the task
if(selectedRoles.indexOf(task.Roles[i].RoleID) >= 0){
// Create this role and add it to our task
task.Roles.push(createRole('Role ' + task.Roles[i].RoleID, task.Roles[i].RoleID, task.Roles[i].RoleID));
}
}
}
});
console.log(tasks)
function createRole(RoleName, RoleID, Role){
return {
RoleName: RoleName,
RoleID: RoleID,
Role: Role
}
}
Any thoughts on a more clean (and working) way to handle this?
var tasks = [{
"User": {
"FirstName": "Joe",
"LastName": "Dirt",
"selected": false,
"marked": false
},
"Tool": {
"id": 31,
"text": "Admin",
"ToolID": "31",
"ToolName": "Admin",
"ToolSuite": "Enterprise Product"
},
"Roles": []
}, {
"User": {
"FirstName": "Bart",
"LastName": "Simpson",
"selected": false,
"marked": false
},
"Tool": {
"id": 35,
"text": "Wordpress",
"ToolID": "35",
"ToolName": "Wordpress",
"ToolSuite": "Enterprise Product"
},
"Roles": [{
RoleName: 'Role 2',
Role: 2,
RoleID: 2
}]
}];
// New selected roles from list
var selectedRoles = [1, 2, 3];
////////////////////////////////////////////////////////////////////////
/*
Loop over the configured tasks and
if there is not an existing role
matching a role id from "SelectedRoles",
create a new role within that task.
*/
tasks.forEach((task) => {
if(task.Roles.length == 0){
for(var i = 0; i < selectedRoles.length; i++){
task.Roles.push(createRole('Role ' + selectedRoles[i], selectedRoles[i], selectedRoles[i]));
}
}
else{
var concatRoleArr = [];
var roleIdArr = [];
for(var i = 0; i < task.Roles.length; i++){
roleIdArr.push(task.Roles[i].RoleID);
}
for(var i = 0; i < selectedRoles.length; i++){
var roleIndex = roleIdArr.indexOf(selectedRoles[i]);
if(roleIndex < 0){
concatRoleArr.push(createRole('Role ' + selectedRoles[i], selectedRoles[i], selectedRoles[i]));
}
}
task.Roles = task.Roles.concat(concatRoleArr);
}
});
console.log(tasks);
function createRole(RoleName, RoleID, Role){
return {
RoleName: RoleName,
RoleID: RoleID,
Role: Role
}
}
Here is your updated code with what you are after. We changed up your looping. We start with checking if there are any roles at all. If not, we loop through selectedRoles and add each one to the role.
If there are roles existing in the task, we create a new array (concatRoleArr), gather all roleIds into a new array, Then loop through selectedRoles again. If the array of existing role ids does not contain the currently looked at selectedRole (indexOf is -1), then add it to the new concatRoleArr, otherwise, continue. When we are done, concat the task.Roles array with concatRoleArr.
You were running into memory issues because your original code has an infinite loop. You add roles to task.Roles, so the loop just keeps on going because no end of task.Roles is ever reached with your for loop when you keep adding more to it. And it kept adding more because checking indexOf with >= 0 will be true if it EXISTS within the array, which your role always did because you were just looping through existing roles anyway. Checking < 0 checks if it DOES NOT EXIST, since it will return -1.

How To Get Next JSON Item

I am wondering how would I get the next JSON item if I have the key in JavaScript. For example, if I provide the key 'Josh' how would I get the contents of 'Annie' along with the key 'Annie'? Would I have to process the JSON in an array and extract from there?
In addition, I believe that there is a proper term for transforming data from one type to another. Any chance anyone knows what it is... it is just on the tip of my tongue!
{
"friends": {
"Charlie": {
"gender": "female",
"age": "28"
},
"Josh": {
"gender": "male",
"age": "22"
},
"Annie": {
"gender": "female",
"age": "24"
}
}
}
In JavaScript the order of Object properties is not guaranteed (ECMAScript Third Edition (pdf):)
4.3.3 Object An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive
value, object, or function. A function stored in a property of an
object is called a method.
If the order doesn't have to be guaranteed you could do the following:
var t = {
"friends": {
"Charlie": {
"gender": "female",
"age": "28"
},
"Josh": {
"gender": "male",
"age": "22"
},
"Annie": {
"gender": "female",
"age": "24"
}
}
};
// Get all the keys in the object
var keys = Object.keys(t.friends);
// Get the index of the key Josh
var index = keys.indexOf("Josh");
// Get the details of the next person
var nextPersonName = keys[index+1];
var nextPerson = t.friends[nextPersonName];
If order matters I would recommend having another array of to hold the order of the names ["Charlie", "Josh", "Annie"] instead of using Object.keys().
var t = ...;
// Hard code value of keys to make sure the order says the same
var keys = ["Charlie", "Josh", "Annie"];
// Get the index of the key Josh
var index = keys.indexOf("Josh");
// Get the details of the next person
var nextPersonName = keys[index+1];
var nextPerson = t.friends[nextPersonName];

Categories