How to compare 2 object in react JS and get the values - javascript

I have 2 state
console.log(this.state.tempWilayahUser)
console.log(this.state.wilayahUser)
how to get row when have same value of id_rt ?

You can use filter() function to achieve this. You can read the docs here.
const state1 = [];
const state2 = [];
const itemsWithIdRtFromState1 = state1.filter(item1 => {
return state2.filter(item2 => item2?.id_rt === item1?.id_rt)
});
const itemsWithIdRtFromState2 = state2.filter(item2 => {
return state1.filter(item1 => item1?.id_rt === item2?.id_rt)
});

Related

Is there a way to simplify this snippet?

const navTitle = document.querySelectorAll(".nav-sec");
const subTitle = document.querySelector(".subtitle");
const artTexts = document.querySelectorAll(".art-text");
const sectionTitles = document.querySelectorAll(".section_title");
const footerContent = document.querySelector(".footer_content");
const projectsTitle = document.querySelectorAll(".title-project");
const projectsDescription = document.querySelectorAll(".desc-project");
const aboutTitle = document.querySelectorAll(".about_title");
const contactContent = document.querySelector(".contact_content");
const aboutContent = document.querySelectorAll(".about_content");
btnLang.addEventListener("click", () => {
const attr = (btnEnglish.classList.contains("hiddden") ? btnPortuguese : btnEnglish).getAttribute("language");
navTitle.forEach((el, index) => (el.textContent = data[attr].navbar[index]));
sectionTitles.forEach((title, index) => (title.textContent = data[attr].navbar[index]));
projectsTitle.forEach((project_titles, index) => (project_titles.textContent = data[attr].project_titles[index]));
projectsDescription.forEach((project_description, index) => (project_description.textContent = data[attr].project_description[index]));
aboutTitle.forEach((about_title, index) => (about_title.textContent = data[attr].about_title[index]));
aboutContent.forEach((about_content, index) => (about_content.textContent = data[attr].about_content[index]));
contactContent.textContent = data[attr].contact_content;
subTitle.textContent = data[attr].subtitle;
footerContent.textContent = data[attr].footer_content;
});
I'm a benninger and I know that when you are repeating yourself too much, you can probably simplify things. But how can I approach something like this code? DRY ftw.
Assuming you have the same number of array elements in data as matching elements in the DOM, one approach is to use an array of selectors, each of which is tied to the associated property name on the data. Iterate over the selectors and language properties, then loop over each element matching the selector to assign the same index from the language property.
const selectorsByLangProp = [
['navbar', '.nav-sec'],
['navbar', '.section_title'],
['project_titles', '.title-project'],
['project_description', '.desc-project'],
['about_title', '.about_title'],
['about_content', '.about_content'],
];
btnLang.addEventListener("click", () => {
const attr = (btnEnglish.classList.contains("hiddden") ? btnPortuguese : btnEnglish).getAttribute("language");
const langData = data[attr];
for (const [langProp, selector] of selectorsByLangProp) {
document.querySelectorAll(selector).forEach((elm, i) => {
elm.textContent = langData[langProp][i];
});
}
contactContent.textContent = langData.contact_content;
subTitle.textContent = langData.subtitle;
footerContent.textContent = langData.footer_content;
});
For larger, complicated pages, a nicer approach to this sort of thing would be to construct the HTML directly from the data, instead of having separate selectors and properties. For example, with React, one might be able to do something similar to the following:
const Page = ({ langData }) => (<>
<div>{langData.subTitle}</div>
{
langData.sections.map((sectionData) => (
<section>
<div>{sectionData.project_title}</div>
<div>{sectionData.project_description}</div>
</section>
))
}
<footer>{langData.contact_content} {langData.footer_content}</footer>
</>);
(That isn't working code, but it's an example of what implementing this sort of thing could look like)

map is not a function in testcafe

I am not able to use a map function inside a client function.
export function availableAudioBitrates() {
const getOptionNames = ClientFunction(() => {
const select = document.querySelector('[data-testid=audioBitrate-setting]');
const options = select.querySelectorAll('option');
console.log(typeof options);
//const values = [];
const values = options.map((option) => option.TextContent);
//options.forEach((option) => values.push(option.textContent));
return values;
});
return getOptionNames();
}
I have "options.foreach" statement working, but with map function, it is throwing an error that options.map is not a function.
Check the value of options, its either undefined or not an array. .map() requires an array to run, anything else will cause that error
Because that is a HTMLCollection, not an array.
Use Array.form(select.querrySelectorAll('option')).
export function availableAudioBitrates() {
const getOptionNames = ClientFunction(() => {
const select = document.querySelector('[data-testid=audioBitrate-setting]');
const options = Array.from(select.querySelectorAll('option'));
console.log(typeof options);
//const values = [];
const values = options.map((option) => option.TextContent);
//options.forEach((option) => values.push(option.textContent));
return values;
});
return getOptionNames();
}

How to filter an array by two indvidual strings from an object?

I'm working on a project where I need to filter 13 items by two different select box values, and I'm getting stuck on persisting the filter.
I have two select boxes that I've selected like so:
let pickupLocation = document.querySelector("#pa_location"); //values are 'complete-set', 'neck', 'bridge'.
let pickupType = document.querySelector("#pa_type1"); // Values are 'soapbar', 'dogear', 'short'.
What's Working:
I'm initializing an object like so:
const activeFilters = {};
To populate the values like so:
//Persist the Complete Set / Single
pickupLocation.addEventListener("change", function () {
if (pickupLocation.value === "complete-set") {
activeFilters.location = "set";
} else {
activeFilters.location = "single";
}
});
pickupType.addEventListener("change", function () {
if (pickupType.value === "soapbar") {
activeFilters.type = "soapbar";
} else if (pickupType.value === "dogear") {
activeFilters.type = "dogear";
} else {
activeFilters.type = "short";
}
});
// Returns something like
// {location: single, type: dogear}
I'm trying to filter an array of input elements by their value. I have 13 inputs each with a value containing words like set, single, dogear, soapbar etc.
Where I'm stuck:
I have a filter function that I'm trying to filter the values of these inputs by two values of the activeFilters object:
const performFilter = (covers) => {
let results;
let filteredValues = Object.values(activeFilters);
filteredValues.forEach((value) => {
results = covers.filter((cover) => cover.value.indexOf(value) !== -1);
});
return results;
};
The problem is my function is returning only one of the two words. For instance, if the my activeFilters object is {location: set, type: dogear} the filtered results array contains only one of them. Where am I going wrong?
Edit:
This function returns all inputs that match one of the activeFilters, and I apologize if I wasn't clear above, but I'd like it to match ALL of the Active Filters. Is this possible with the function below?
const performFilter = (covers) => {
let results = []; // initialise the array
let filteredValues = Object.values(activeFilters);
filteredValues.forEach((value) => {
let res = covers.filter((cover) => cover.value.indexOf(value) !== -1);
results.push(...res);
});
console.log(results);
};
CODEPEN:
Codepen!
const performFilter = (covers) => {
let results = []; // initialise the array
let filteredValues = Object.values(activeFilters);
filteredValues.forEach((value) => {
let res = covers.filter((cover) => cover.value.indexOf(value) !== -1);
// push the value it find individually
// you were overriding the previous value with result = filter()
results.push(...res);
});
return results;
};
// according to Edited question
const performFilter = (covers) => {
let results = []; // initialise the array
let filteredValues = Object.values(activeFilters);
return covers.filter((cover) => filteredValues.every(value => cover.value.indexOf(value) !== -1));
};
I'm not sure if I understood clearly your question, so feel free to comment it.
First, I suggest you to filter your covers array and inside the filtering function iterate through your selected filters. This is because the filter function returns the array already filtered and so you don't need to assign it to a result variable or things like that. So based on that, try this:
const performFilter = (covers) => {
let results;
let filteredValues = Object.values(activeFilters);
const filteredCovers = covers.filter((cover) => {
return cover.value.split("-").some((tag) => filteredValues.includes(tag))
});
console.log(filteredCovers)
};

Return array value from produce function | immer.js

I am using immer.js to perform operations on arrays in the state.
Arrays: basicRecipe and recipeBasicRecipe.
I am modifying the draft.basicRecipe in the produce function. My objective is to return the updated "draft.basicRecipe" value and store the same in temparray1.
let temparray1 = produce(state, draft => {
draft.basicRecipe = draft.basicRecipe.map(item => {
let element = draft.recipeBasicRecipes.find(e => e._id === item._id);
console.log(element);
if (element) {
item.details = item.details.map(e => {
let detail = element.details.find(d => d._id === e._id);
if (detail) {
e.rate = detail.rate;
}
return e;
});
}
return item;
});
return draft.basicRecipe;
});
console.log(temparray1);
When I return the draft I am able to see updated basicRecipe nested in output.
I am getting the below error when I try to return the array i.e draft.basicRecipe
[Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft
This code is a mess. You are using map which returns a new array but you're also trying to mutate the original draft object.
This is still unreadable and confusing, but at least by using forEach instead of map we are just mutating and not trying to do two things at once.
let temparray1 = produce(state, (draft) => {
draft.basicRecipe.forEach((item) => {
let element = draft.recipeBasicRecipes.find((e) => e._id === item._id);
if (element) {
item.details.forEach((e) => {
let detail = element.details.find((d) => d._id === e._id);
if (detail) {
e.rate = detail.rate;
}
});
}
});
});

Use lodash cond to take certain branch

I'm trying to use lodash cond to invoke different functions provided different inputs. Perhaps I've misunderstood cond, but I really like the clean approach to conditions.
Basically I have a 2-dimensional data array (grid). A header 1-dimensional header array and a 1-dimensional totals array. The user can choose to add data headers and totals to the data array. The total row can be either at the top or bottom.
This turned into eight conditions like this:
const totalAbove = totalPosition >= 1;
const totalBelow = totalPosition <= -1;
const hasLabelsAndTotalsAbove = showLables && totalAbove;
const hasLabelsAndTotalsBelow = showLables && totalBelow;
const noLabelsAndTotalsAbove = !showLables && totalAbove;
const noLabelsAndTotalsBelow = !showLables && totalBelow;
const noTotalHasLabels = showLables && !hasTotalRow;
const noTotalNoLabels = !showLables && !hasTotalRow;
Then I thought I could do the this:
const getData = cond([
[hasLabelsAndTotalsAbove, () => Array.prototype.concat([headers], [totalRow], ...matrixes)],
[hasLabelsAndTotalsBelow, () => Array.prototype.concat([headers], ...matrixes, [totalRow])],
[noLabelsAndTotalsAbove, () => Array.prototype.concat([totalRow], ...matrixes)],
[noLabelsAndTotalsBelow, () => Array.prototype.concat(...matrixes, [totalRow]) ],
[noTotalHasLabels, () => Array.prototype.concat([headers], ...matrixes) ],
[noTotalNoLabels, () => matrixes ]
]);
data = getData();
The above should combine the three arrays into the desired form by concatenating them in the right order. But the result is just undefined. Have I completely misunderstood cond?
For now I've just turned the _cond part into if...else statements, but I find the cond approach cleaner.
You have to use _.matches or other function that allows you to pick a property in some object, with getData you don't have context, because you don't pass anything, and _.cond returns a function that works against an object. If you want to test if hasLabelsAndTotalsAbove is true and execute some logic, you can create an object and pass it to the function returned by _.cond:
const totalPosition = 2;
const showLabels = true;
const hasTotalRow = true;
const totalAbove = totalPosition >= 1;
const totalBelow = totalPosition <= -1;
const definitions = {
hasLabelsAndTotalsAbove: showLabels && totalAbove,
hasLabelsAndTotalsBelow: showLabels && totalBelow,
noLabelsAndTotalsAbove: !showLabels && totalAbove,
noLabelsAndTotalsBelow: !showLabels && totalBelow,
noTotalHasLabels: showLabels && !hasTotalRow,
noTotalNoLabels: !showLabels && !hasTotalRow
};
const m = a => _.matches({ [a]: true });
const getData = _.cond([
[m('hasLabelsAndTotalsAbove'), () => 'Action: hasLabelsAndTotalsAbove'],
[m('hasLabelsAndTotalsBelow'), () => 'Action: hasLabelsAndTotalsBelow'],
[m('noLabelsAndTotalsAbove'), () => 'Action: noLabelsAndTotalsAbove'],
[m('noLabelsAndTotalsBelow'), () => 'Action: noLabelsAndTotalsBelow'],
[m('noTotalHasLabels'), () => 'Action: noTotalHasLabels'],
[m('noTotalNoLabels'), () => 'Action: noTotalNoLabels']
]);
console.log(getData(definitions));
This allows us to select the action to execute if some property of the object evaluates to true.

Categories

Resources