JS Creating Dynamic generateItems Not working - javascript

I currently have minimal code for this question but I'm hoping it's something simple that I am missing. What I am trying to do is to create three individual drag and drop boxes with a dynamic array. This is the array:
const col2 = ["Restoration Events", "Spectrum Utilization", "Segment Utilization"]
and here the code from this.state that is generating the three items:
items2: generateItems(3, (i) => ({ id: '2' + i, data: col2 }))
This code initially was:
items2: generateItems(1, (i) => ({ id: '2' + i, data: `Card 2 - ${i}`}))
which generated three boxes with a generic Card 2 + number, which is not what we are needing. I'm hoping there is something simple I am missing that will allow me to do this. Please forgive the limited code and any help is appreciated.

it's kind of hard to understand what you want to achieve and what the context is.
I'll try to guess what you want to achieve and maybe that will help you.
Since I have not enough reputation I unfortunately cannot use the comment function.
Most probably you are developing a React-Component (because you are referring to this.state) and you somewhere found the code
constructor(props){
...
this.state = {
items2: generateItems(1, (i) => ({ id: '2' + i, data: `Card 2 - ${i}` }))
}
...
}
Since you did not provide code for generateItems I can only guess that it may generate some object and incorporates the output from given inline function somehow.
My impression is, that you wanted to change it a way that the data: key will have one value from your array based on the index.
You could achieve this in the following way, but keep in mind that I did not take the function generateItems into consideration because the code is missing.
...
const col2 = ["Restoration Events", "Spectrum Utilization", "Segment Utilization"]
this.state = {
items2: generateItems(3, (i) => ({ id: '2' + i, data: col2[i] }))
}
...
This might point you in the right direction if my guess is correct, but you have
to provide more details. Otherwise nobody will be able to help you.

Related

React - How to map from two SQL tables simultaneously?

I am pulling from a SQL table device, and displaying its content to a table by mapping from device. I am trying to add a column that pulls information from another SQL table, group, but I haven't figured out how to adjust the mapping in order to pull from both device and group. I am sure the issue is caused since group isn't declared in this scope but I cannot solve how it should be declared in this portion of the script.
Both tables shared a common column, group_id, and I have added useSelector for both:
const device = useSelector((state) => state.device);
const group = useSelector((state) => state.group);
<Table
tableHeaderColor="warning"
tableHead={['Device Name', 'Location', 'Group', 'Release Version']}
tableData={device.deviceData.map((device) => {
return [
device['device_name'],
device['location_name'],
group['group_name'],
device['release'],
];
})}
/>
An alternative fix I have tried is finding the group_name since both tables device and group share the group_id column, but it causes a group.find is not a function error. I am unsure if my syntax is incorrect, as I'm working from this site as a resource.
tableData={device.deviceData.map((device) => {
return [
device['device_name'],
device['location_name'],
group.find(group => group.group_id === device.group_id).group_name,
device['release'],
];
})}
Many thanks for any advice
UPDATE:
Thank you for the answers and comments so far. Here is some additional information:
The reducer does contain the initial state empty array for group (groupdata)
const initialState = {
groupData: [],
result: '',
};
Here are the screenshots of the SQL tables device and group. They do not have the same number of entries, as group lists the groups that a number of devices can be assigned to. Hence there are many more entries under device than group.
device SQL table
group SQL table
If you using group.find you need to make sure the reducer contains the initial state empty array for group
Doing this in a map in the actual JSX might get a bit confusing since you're pulling from two different datasources. Also, assuming that the array in
device.deviceData and the group array share the same number of entries and correlate to each other, searching in group on each loop through device.deviceData seems like an unnecessary performance hit. My preference might be to create my source data in a plain for loop outside of the return JSX, and then just plug it in directly:
let tableData = []
for (let i = 0; i < device.deviceData.length; i += 1) {
const currentDevice = device.deviceData[i];
const currentGroup = group[i];
const entry = [
currentDevice['device_name'],
currentDevice['location_name'],
currentGroup['group_name'],
currentDevice['release'],
];
tableData.push(entry);
}
Then I would simply pass tableData to the <Table /> tableData prop.
I think group is an object and has a structure similar to device.deviceData. By that assumption, group.groupData should be the array which will be useful to us.
What we can do is build a Map of group_id -> group_name which we use later for getting relevant device group_name in Table component.
Here is a code snippet which should give you an idea (this is a JS based answer. I think your use-case can make use of joins at sql level for less work here) :-
const device = {
deviceData: [{
group_id: 1
},
{
group_id: 2
}
]
}
const group = {
groupData: [{
group_id: 1,
group_name: 'Group-1'
},
{
group_id: 2,
group_name: 'Group-2'
}
]
}
const buildMap = () => {
const gMap = {};
for (const {
group_id,
group_name
} of group.groupData) {
gMap[group_id] = group_name;
}
return gMap;
}
const groupMap = buildMap();
device.deviceData.forEach(d => console.log(groupMap[d.group_id]));

ReactJS Complex Form Input Field Duplicating Text in Multiple Input Fields

I have a form where you can add/remove groups and input items, I was able to get the groups of input field working, but I'm having trouble with the items input within the respected groups:
I created a code sand box here: https://codesandbox.io/s/twilight-cache-4ipv6?file=/src/Form.jsx
If you click on Add Items + button, and type in the item fields, the value duplicates to all the fields.
Also, sometimes I feel like the x button doesn't work, and will only remove the last item or something, I believe this is "controlled component?"
In addition, I want to ask if there's a better method on what I'm doing? It seems like there's a lot of complexities in the code I'm trying to write up. I feel like I'm writing too much of the set state hooks.
I think we don't need that fields state.
And we can update Add Handlers like this
const handleAddGroup = i => {
const newGroup = [...group];
newGroup.push({
id: null,
cat: "",
items: [
{
name: "",
value: ""
}
]
});
setGroups(newGroup);
};
const handleAddField = i => {
setGroups(state => {
const stateCopy = JSON.parse(JSON.stringify(state));
stateCopy[i].items.push({
name: "",
value: ""
});
return stateCopy;
});
};
https://codesandbox.io/s/cool-frog-2yrlt

Is there some kind of find method on Arrays that returns [item | undefined] rather than item | undefined?

Here is some code from I project I am working in:
const profile = userdataDocs
.filter(isValidUserdataDocument)
.find((document: ICouchDBDocumentDoc) => document._id === profileId);
if (profile) {
return {
id: hashSensitive(profile._id, environment),
type: profile.type,
creationDate: profile.creationDate,
updatedDate: profile.updatedDate,
entityVersion: profile.entityVersion,
};
}
Here is how I would like to have my code look:
return userdataDocs
.filter(isValidUserdataDocument)
.filter((document: ICouchDBDocumentDoc) => document._id === profileId)
.map((profile: ICouchDBDocumentDoc) => ({
id: hashSensitive(profile._id, environment),
type: profile.type,
creationDate: profile.creationDate,
updatedDate: profile.updatedDate,
entityVersion: profile.entityVersion,
}))
.slice(0, 1);
But I get feedback from the rest of my team that I should not use filter because it will continue searching after having found an item. Premature optimization in mind, but still a pretty valid and popular opinion.
Is there some other array method (or altogether different solution) that I can use to write code the way I want, with 'pipes', without getting the performance penalty of moving from find to filter?
Also let me know if I am an idiot and should let go of the pipe dream (pun intended).
Let me start that I like the first solution. In my opinion, it looks good.
But if you are really desperate for a solution that fulfills your pipe dream
const array = [10, 20, 30];
function singleMapFind(args, fn) {
const currentArray = args[2];
const duplicate = [...currentArray];
currentArray.splice(1, currentArray.length - 1);
return duplicate.find(fn);
}
const modified = array.map((...args) => singleMapFind(args, (e) => e > 20));
I would never use it though. Wish you luck with the PR.

Hi I want to filter the data in nested array with condition only through filter function [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
let assume I have a list and i want to check the income length is more than 3 digits..
const list=[ {name:'Jhon',income:100},{name:'Ellen',income:100},{name:'joe',income:1500}
]
const newList=list.filter((sal) => sal.income.length > 3)
Explanation
Okay, so first off, in JavaScript, and most other languages, you can't just have some data like what you've done 1000$, you best store this kind of data as a string, like I've done in my answer, that will only cause errors in your code.
Then of course, with my answer, you want to get the numeric value of the income, hence the need of parseInt, this function will ignore some chars like in this case '$', then you can check if the income is greater than 1,000.
Another note, I'm not sure why you tried that syntax with {name} => ..., but there's no need to do it like that, in this scenario, there's no need for the curly braces at all. If anything, if you were to do it like ({name}) => ..., that would only return the name property from the current object, you won't even be able to access the income property.
const list = [{
name: 'Jhon',
income: '1000$'
}, {
name: 'Ellen',
income: '1200$'
}, {
name: 'joe',
income: '1500$'
}]
const newList = list.filter(i => parseInt(i.income) > 1000);
console.log(newList);
First off, the property values need to be integers with the dollar sign removed:
const list = [
{
name:'Jhon',
income:1000
}, {
name:'Ellen',
income:1200
}, {
name:'joe',
income:1500
}
];
And now you just need to make your function work. Here is how you could do it:
const list = [
{
name:'Jhon',
income:1000
}, {
name:'Ellen',
income:1200
}, {
name:'joe',
income:1500
}
];
var newList = list.filter(e => e.income > 1000);
newList.forEach((e, i) => newList[i] = e.income);
console.log(newList);

Javascript/Ramda: How to make the following code functional

Hi I have the following object structure,
const usersList = {
NFr9F4WbBxR4H5ajolbS6q0skPF2: {
name: "justin davidson",
uid: "NFr9F4WbBxR4H5ajolbS6q0skPF2"
},
asas9F4WbBxR4H5ajolbS6q0sasF2: {
name: "sawyer davidson",
uid: "asas9F4WbBxR4H5ajolbS6q0sasF2"
}
}
It has a user ID as key, and it's user object nested within. I want to store the inner user data. I've been using Ramda JS and have done so by doing the following,
let x = []
const y = R.keys(usersList).forEach((uid) => {
x.push(usersList[uid])
return x
})
which returns
[{"name":"justin davidson","uid":"NFr9F4WbBxR4H5ajolbS6q0skPF2"},
{"name":"sawyer davidson","uid":"asas9F4WbBxR4H5ajolbS6q0sasF2"}]
..however I'd like achieve the same in a purely functional way. What would be the best approach here? I'm guessing compose and map but I can't seem to work it out. Looking for a little direction.
Thanks
Just use map instead of forEach:
const x = R.keys(usersList).map((uid) => usersList[uid])
It looks like there's also a values method that does what you want:
const x = R.values(usersList)
There isn't always a function tucked away in some lib that does exactly what you want it to do. Showing how to do things on your own demonstrates that you don't have to feel "stuck" when you're faced with a problem and you can't find a magical function to solve it for you. Once you learn the function exists, sure, go ahead and replace your home-brew solution with the built-in. But until then, don't be afraid to write code and move on.
// ovalues :: (Object k:v) -> [v]
const ovalues = o =>
Array.from(Object.keys(o), k => o[k])
const usersList = {
NFr9F4WbBxR4H5ajolbS6q0skPF2: {
name: "justin davidson",
uid: "NFr9F4WbBxR4H5ajolbS6q0skPF2"
},
asas9F4WbBxR4H5ajolbS6q0sasF2: {
name: "sawyer davidson",
uid: "asas9F4WbBxR4H5ajolbS6q0sasF2"
}
}
console.log(ovalues(usersList))
So yep, R.values does exist in the Rambda library, but next time don't be afraid to try to solve it on your own. You have a powerful brain, now use it ^_^

Categories