I have a function which takes the input from the form and runs the some method on the Array prototype, and I am then changing state in the isInAPI && wasAPICallMade (i've inserted the data in a code snippet) essentially if I should be getting something either way as the wasAPICallMade state is getting updated, but it's not.
What am I doing wrong?
indgredients[{
id: 1,
name: 'Hemp Protein'
}, {
id: 2,
name: 'Avocado'
}, {
id: 3,
name: 'Organic Maca'
}, {
id: 4,
name: 'Organic Kale'
}, {
id: 5,
name: 'Organic Coconut Water'
}, {
id: 6,
name: 'Astragalus'
}, {
id: 7,
name: 'Rhodiola'
}, {
id: 8,
name: 'Other Spices'
}, {
id: 9,
name: 'Green Coffee Beans'
}, {
id: 10,
name: 'Organic Peach'
}, {
id: 11,
name: 'Organic Seabuckthorn'
}, {
id: 12,
name: 'Hijiki Seaweed'
}, {
id: 13,
name: 'Organic Turmeric'
}, {
id: 14,
name: 'Organic Ginger'
}, {
id: 15,
name: 'Lime Juice'
}, {
id: 16,
name: 'Bell Pepper'
}, {
id: 17,
name: 'Organic Spinach'
}, {
id: 18,
name: 'Organic Flax Seeds'
}, {
id: 19,
name: 'Organic Goji Berry'
}, {
id: 20,
name: 'Organic Chlorella'
}, {
id: 21,
name: 'Organic Nutmeg'
}, {
id: 22,
name: 'Kale'
}, {
id: 23,
name: 'Tomato2'
}, {
id: 24,
name: 'Organic Cucumber'
}, {
id: 25,
name: 'Tamari'
}, {
id: 26,
name: 'Organic Cacao'
}, {
id: 27,
name: 'Chaga Mushroom'
}, {
id: 28,
name: 'Raw Cashew'
}, {
id: 29,
name: 'Lemon'
}, {
id: 30,
name: 'Organic Cold Brew Coffee'
}, {
id: 31,
name: 'Organic Sweet Cherry'
}, {
id: 32,
name: 'Japanese Matcha Green Tea'
}, {
id: 33,
name: 'Pink Himalayan Sea Salt'
}, {
id: 34,
name: 'Organic Coconut'
}, {
id: 35,
name: 'Watermelon'
}, {
id: 36,
name: 'Organic Wheatgrass'
}, {
id: 37,
name: 'Coconut Milk'
}, {
id: 38,
name: 'Oats'
}, {
id: 39,
name: 'Shiitake + Crimini Mushrooms'
}, {
id: 40,
name: 'Organic Apple'
}, {
id: 41,
name: 'Organic Camu Camu'
}, {
id: 42,
name: 'Organic Zucchini'
}, {
id: 43,
name: 'Organic Pea Protein'
}, {
id: 44,
name: 'Chia Seed'
}, {
id: 45,
name: 'Spinach'
}, {
id: 46,
name: 'Organic Acerola Cherry'
}, {
id: 47,
name: 'Butternut Squash Noodles'
}, {
id: 48,
name: 'Sweet Potato'
}, {
id: 49,
name: 'Galangal'
}, {
id: 50,
name: 'Basil'
}, {
id: 51,
name: 'Organic Raspberry'
}, {
id: 52,
name: 'Black Garlic'
}, {
id: 53,
name: 'Zucchini'
}, {
id: 54,
name: 'Organic Peppermint'
}, {
id: 55,
name: 'Raw Pumpkin Seed'
}, {
id: 56,
name: 'Golden Figs'
}, {
id: 57,
name: 'Papaya'
}, {
id: 58,
name: 'Dulse Seaweed'
}, {
id: 59,
name: 'Garlic'
}, {
id: 60,
name: 'Madras Curry'
}, {
id: 61,
name: 'Cordyceps Mushroom'
}, {
id: 62,
name: 'Tomato'
}, {
id: 63,
name: 'Reishi Mushroom'
}, {
id: 64,
name: 'Cinnamon'
}, {
id: 65,
name: 'Red Miso'
}, {
id: 66,
name: 'Macadamia Nut'
}, {
id: 67,
name: 'Organic Acai Berry'
}, {
id: 68,
name: 'Raw Almond'
}, {
id: 69,
name: 'Chickpea'
}, {
id: 70,
name: 'Organic Mango'
}, {
id: 71,
name: 'Organic Coconut Oil'
}, {
id: 72,
name: 'Organic Pineapple'
}, {
id: 73,
name: 'Organic Celery'
}, {
id: 74,
name: 'Scallion'
}, {
id: 75,
name: 'Organic Vanilla Bean'
}, {
id: 76,
name: 'Ginger'
}, {
id: 77,
name: 'Cauliflower'
}, {
id: 78,
name: 'Raw Walnut'
}, {
id: 79,
name: 'Organic Blueberry'
}, {
id: 80,
name: 'Organic Date'
}, {
id: 81,
name: 'Organic Banana'
}, {
id: 82,
name: 'Rosemary'
}, {
id: 83,
name: 'Vanilla Bean'
}, {
id: 84,
name: 'Ginseng'
}, {
id: 85,
name: 'Organic Strawberry'
}, {
id: 86,
name: 'Carrot'
}, {
id: 87,
name: 'Oregano'
}, {
id: 88,
name: 'Lemon2'
}, {
id: 89,
name: 'Organic Garbanzo Beans'
}, {
id: 90,
name: 'Organic Blackberry'
}, {
id: 91,
name: 'Organic Raw Almond Butter'
}, {
id: 92,
name: 'Pecans'
}, {
id: 93,
name: 'Organic Mulberry'
}, {
id: 94,
name: 'Organic Pepper'
}, {
id: 95,
name: 'Organic Hemp Seed'
}, {
id: 96,
name: 'Organic Pumpkin'
}, {
id: 97,
name: 'Organic Blue Majik'
}, {
id: 98,
name: 'Organic Gluten-Free Oats'
}, {
id: 99,
name: 'Organic Cardamom'
}, {
id: 100,
name: 'Lemon Juice'
},
import React, { useState } from 'react'
import Alert from '#material-ui/lab/Alert'
import TextField from '#material-ui/core/TextField'
import Grid from '#material-ui/core/Grid'
import { makeStyles } from '#material-ui/core/styles'
var useStyles = makeStyles((theme) => ({
root: {
'& > *': {
margin: theme.spacing(1),
width: '25ch',
},
submit: {
color: 'red',
},
},
}))
var IngredientInput = ({ indgredients, products }) => {
var [indgredients, setIngredients] = useState(indgredients)
var [text, setText] = useState('')
var [isInAPI, setIsInAPI] = useState(false)
var [wasAPICallMade, setWastAPICallMade] = useState(false)
function CheckIngredients(input) {
if (indgredients.some((item) => item.name === input)) {
setIsInAPI((prevState) => !prevState)
console.log('isInAPI ', isInAPI)
setWastAPICallMade((prevState) => !prevState)
console.log('wasAPICallMade ', wasAPICallMade)
}
}
function handleTextChange(e) {
console.log('e', e.target.value)
setText(e.target.value)
}
function handleSubmit(e) {
e.preventDefault()
CheckIngredients(text)
setText('')
}
var classes = useStyles()
return (
<>
<Grid container justify="center">
<form onSubmit={handleSubmit} className={classes.root}>
<TextField
value={text}
onChange={handleTextChange}
id="outlined-basic"
label="Outlined"
variant="outlined"
/>
<button type="submit" className={classes.submit}>
{' '}
Check Ingredient{' '}
</button>
</form>
{wasAPICallMade ? (
isInAPI ? (
<Alert severity="success">
This is a success alert — check it out!
</Alert>
) : (
<Alert severity="error">
This is an error alert — check it out!
</Alert>
)
) : null}
</Grid>
</>
)
}
export default IngredientInput
Update
Based on what Emile and Lanxion suggested I tried this:
useEffect(() => {
console.log('isInAPI in useEffect', isInAPI)
console.log('wasAPICallMade in useEffect', wasAPICallMade)
}, [isInAPI, wasAPICallMade])
function CheckIngredients(input) {
setWastAPICallMade(true)
var found = indgredients.some((item) => item.name === input)
console.log('found ', found)
if (found) {
setIsInAPI(true)
console.log('isInAPI ', isInAPI)
}
}
Now two questions with this change:
I'm correct in understanding useEffect will fire on the initial render and everytime changes to those variables are made? If not, useEffect won't fire.
So in the CheckIngredients function setWastAPICallMade(true) gets ignored?
Also why doesn't var found = indgredients.some((item) => item.name === input) have the correct response???
function CheckIngredients(input) {
setWastAPICallMade(true)
var found = indgredients.some((item) => item.name === input)
console.log('found ', found)
if (found) {
setIsInAPI(true)
console.log('isInAPI ', isInAPI)
}
}
Most likely, your state is being updated, but useState hook functions are asynchronous, so if you log the state right in the next line, it may not reflect the change immediately. If you would like to check the value of a specific state after change to it, you can use a useEffect hook with the second value as the state variable that you are watching.
useEffect(() => {
console.log('isInAPI ', isInAPI);
console.log('wasAPICallMade ', wasAPICallMade)
}, [isInAPI, wasAPICallMade])// This is be executed when "isinApi" or "wasAPICallMade" state changes
Related
I am trying to render a Component and getting error collections.map is not a function. below is the attached file of my SHOP_DATA and CollectionOverview. I am importing data from the SHOP_DATA file and in other components it's working fine. I am also getting error like Cannot read property 'toUpperCase' of undefined.
import React, { useState } from "react";
import "./CollectionOverview.scss";
import CollectionPreview from "../CollectionPreview/CollectionPreview";
import SHOP_DATA from "../../Pages/Shop/Shop_data";
const CollectionOverview = () => {
const [collections] = useState(SHOP_DATA);
return (
<div>
{collections.map(({ id, title, items }) => (
<CollectionPreview key={id} title={title} items={items} />
))}
</div>
);
};
export default CollectionOverview;
This is my SHOP_DATA from which i am importing data to my CollectionOverview Component.
const SHOP_DATA = {
hats: {
id: 1,
title: "Hats",
routeName: "hats",
items: [
{
id: 1,
name: "Brown Brim",
imageUrl: "https://i.ibb.co/ZYW3VTp/brown-brim.png",
price: 25,
},
{
id: 2,
name: "Blue Beanie",
imageUrl: "https://i.ibb.co/ypkgK0X/blue-beanie.png",
price: 18,
},
{
id: 3,
name: "Brown Cowboy",
imageUrl: "https://i.ibb.co/QdJwgmp/brown-cowboy.png",
price: 35,
},
{
id: 4,
name: "Grey Brim",
imageUrl: "https://i.ibb.co/RjBLWxB/grey-brim.png",
price: 25,
},
{
id: 5,
name: "Green Beanie",
imageUrl: "https://i.ibb.co/YTjW3vF/green-beanie.png",
price: 18,
},
{
id: 6,
name: "Palm Tree Cap",
imageUrl: "https://i.ibb.co/rKBDvJX/palm-tree-cap.png",
price: 14,
},
{
id: 7,
name: "Red Beanie",
imageUrl: "https://i.ibb.co/bLB646Z/red-beanie.png",
price: 18,
},
{
id: 8,
name: "Wolf Cap",
imageUrl: "https://i.ibb.co/1f2nWMM/wolf-cap.png",
price: 14,
},
{
id: 9,
name: "Blue Snapback",
imageUrl: "https://i.ibb.co/X2VJP2W/blue-snapback.png",
price: 16,
},
],
},
sneakers: {
id: 2,
title: "Sneakers",
routeName: "sneakers",
items: [
{
id: 10,
name: "Adidas NMD",
imageUrl: "https://i.ibb.co/0s3pdnc/adidas-nmd.png",
price: 220,
},
{
id: 11,
name: "Adidas Yeezy",
imageUrl: "https://i.ibb.co/dJbG1cT/yeezy.png",
price: 280,
},
{
id: 12,
name: "Black Converse",
imageUrl: "https://i.ibb.co/bPmVXyP/black-converse.png",
price: 110,
},
{
id: 13,
name: "Nike White AirForce",
imageUrl: "https://i.ibb.co/1RcFPk0/white-nike-high-tops.png",
price: 160,
},
{
id: 14,
name: "Nike Red High Tops",
imageUrl: "https://i.ibb.co/QcvzydB/nikes-red.png",
price: 160,
},
{
id: 15,
name: "Nike Brown High Tops",
imageUrl: "https://i.ibb.co/fMTV342/nike-brown.png",
price: 160,
},
{
id: 16,
name: "Air Jordan Limited",
imageUrl: "https://i.ibb.co/w4k6Ws9/nike-funky.png",
price: 190,
},
{
id: 17,
name: "Timberlands",
imageUrl: "https://i.ibb.co/Mhh6wBg/timberlands.png",
price: 200,
},
],
},
jackets: {
id: 3,
title: "Jackets",
routeName: "jackets",
items: [
{
id: 18,
name: "Black Jean Shearling",
imageUrl: "https://i.ibb.co/XzcwL5s/black-shearling.png",
price: 125,
},
{
id: 19,
name: "Blue Jean Jacket",
imageUrl: "https://i.ibb.co/mJS6vz0/blue-jean-jacket.png",
price: 90,
},
{
id: 20,
name: "Grey Jean Jacket",
imageUrl: "https://i.ibb.co/N71k1ML/grey-jean-jacket.png",
price: 90,
},
{
id: 21,
name: "Brown Shearling",
imageUrl: "https://i.ibb.co/s96FpdP/brown-shearling.png",
price: 165,
},
{
id: 22,
name: "Tan Trench",
imageUrl: "https://i.ibb.co/M6hHc3F/brown-trench.png",
price: 185,
},
],
},
womens: {
id: 4,
title: "Womens",
routeName: "womens",
items: [
{
id: 23,
name: "Blue Tanktop",
imageUrl: "https://i.ibb.co/7CQVJNm/blue-tank.png",
price: 25,
},
{
id: 24,
name: "Floral Blouse",
imageUrl: "https://i.ibb.co/4W2DGKm/floral-blouse.png",
price: 20,
},
{
id: 25,
name: "Floral Dress",
imageUrl: "https://i.ibb.co/KV18Ysr/floral-skirt.png",
price: 80,
},
{
id: 26,
name: "Red Dots Dress",
imageUrl: "https://i.ibb.co/N3BN1bh/red-polka-dot-dress.png",
price: 80,
},
{
id: 27,
name: "Striped Sweater",
imageUrl: "https://i.ibb.co/KmSkMbH/striped-sweater.png",
price: 45,
},
{
id: 28,
name: "Yellow Track Suit",
imageUrl: "https://i.ibb.co/v1cvwNf/yellow-track-suit.png",
price: 135,
},
{
id: 29,
name: "White Blouse",
imageUrl: "https://i.ibb.co/qBcrsJg/white-vest.png",
price: 20,
},
],
},
mens: {
id: 5,
title: "Mens",
routeName: "mens",
items: [
{
id: 30,
name: "Camo Down Vest",
imageUrl: "https://i.ibb.co/xJS0T3Y/camo-vest.png",
price: 325,
},
{
id: 31,
name: "Floral T-shirt",
imageUrl: "https://i.ibb.co/qMQ75QZ/floral-shirt.png",
price: 20,
},
{
id: 32,
name: "Black & White Longsleeve",
imageUrl: "https://i.ibb.co/55z32tw/long-sleeve.png",
price: 25,
},
{
id: 33,
name: "Pink T-shirt",
imageUrl: "https://i.ibb.co/RvwnBL8/pink-shirt.png",
price: 25,
},
{
id: 34,
name: "Jean Long Sleeve",
imageUrl: "https://i.ibb.co/VpW4x5t/roll-up-jean-shirt.png",
price: 40,
},
{
id: 35,
name: "Burgundy T-shirt",
imageUrl: "https://i.ibb.co/mh3VM1f/polka-dot-shirt.png",
price: 25,
},
],
},
};
export default SHOP_DATA;
map function is not native to objects. It is used to iterate an array and it also returns an array, and you are using it on objects. This is the correct implementation.
import React, { useState } from "react";
import "./CollectionOverview.scss";
import CollectionPreview from "../CollectionPreview/CollectionPreview";
import SHOP_DATA from "../../Pages/Shop/Shop_data";
const CollectionOverview = () => {
const [collections] = useState(SHOP_DATA);
return (
<div>
{Object.values(collections).map(({ id, title, items }) => (
<CollectionPreview key={id} title={title} items={items} />
))}
</div>
);
};
export default CollectionOverview;
I have this array on input :
const categories = [
{ id: 9, name: 'General Knowledge' },
{ id: 10, name: 'Entertainment: Books' },
{ id: 11, name: 'Entertainment: Film' },
{ id: 12, name: 'Entertainment: Music' },
{ id: 13, name: 'Entertainment: Musicals & Theatres' },
{ id: 14, name: 'Entertainment: Television' },
{ id: 15, name: 'Entertainment: Video Games' },
{ id: 16, name: 'Entertainment: Board Games' },
{ id: 17, name: 'Science & Nature' },
{ id: 18, name: 'Science: Computers' },
{ id: 19, name: 'Science: Mathematics' },
{ id: 20, name: 'Mythology' },
{ id: 21, name: 'Sports' },
{ id: 22, name: 'Geography' },
{ id: 23, name: 'History' },
{ id: 24, name: 'Politics' },
{ id: 25, name: 'Art' },
{ id: 26, name: 'Celebrities' },
{ id: 27, name: 'Animals' },
{ id: 28, name: 'Vehicles' },
{ id: 29, name: 'Entertainment: Comics' },
{ id: 30, name: 'Science: Gadgets' },
{ id: 31, name: 'Entertainment: Japanese Anime & Manga' },
{ id: 32, name: 'Entertainment: Cartoon & Animations' }
]
I need to translate all the keys name of my objects.
For that, I use the google translation API.
here is the code :
googleTranslate.translate(categories.map(i => i.name), 'en', 'fr', function(err, translations) {
console.log(translations.map(tr => tr.translatedText))
})
So the result is :
[ 'Culture générale',
'Divertissement: livres',
'Divertissement: Film',
'Divertissement: Musique',
'Divertissement: comédies musicales et théâtres',
'Divertissement: Télévision',
'Divertissement: jeux vidéo',
'Divertissement: jeux de société',
'Science et nature',
'Science: Informatique',
'Science: Mathématiques',
'Mythologie',
'Des sports',
'La géographie',
'L\'histoire',
'Politique',
'Art',
'Célébrités',
'Animaux',
'Véhicules',
'Divertissement: BD',
'Science: Gadgets',
'Divertissement: anime et manga japonais',
'Divertissement: dessin animé et animations' ]
But I would like to keep the structure of the first array. Only update the keys name with the translations.
Output :
const categories = [
{ id: 9, name: 'Culture générale' },
{ id: 10, name: 'Divertissement: livres' },
{ id: 11, name: 'Divertissement: Film' },
{ id: 12, name: 'Divertissement: Musique' },
{ id: 13, name: 'Divertissement: comédies musicales et théâtres' },
{ id: 14, name: 'Divertissement: Télévision' },
{ id: 15, name: 'Divertissement: jeux vidéo' },
{ id: 16, name: 'Divertissement: jeux de société' },
{ id: 17, name: 'Science et nature' },
{ id: 18, name: 'Science: Informatique' },
{ id: 19, name: 'Science: Mathématiques' },
{ id: 20, name: 'Mythologie' },
{ id: 21, name: 'Des sports' },
{ id: 22, name: 'La géographie' },
{ id: 23, name: 'L\'histoire' },
{ id: 24, name: 'Politique' },
{ id: 25, name: 'Art' },
{ id: 26, name: 'Célébrités' },
{ id: 27, name: 'Animaux' },
{ id: 28, name: 'Véhicules' },
{ id: 29, name: 'Divertissement: BD' },
{ id: 30, name: 'Science: Gadgets' },
{ id: 31, name: 'Divertissement: anime et manga japonais' },
{ id: 32, name: 'Divertissement: dessin animé et animations' }
]
I have not found how to do it yet.
Thanks in advance for your time.
The simplest way is:
googleTranslate.translate(categories.map(i => i.name), 'en', 'fr', function(err, translations) {
console.log(translations.map(tr => {
id: tr.id,
name: tr.name
}
))
})
You could recreate the old structure after the translation:
const categories [...];
const translatedCategories = new Array();
googleTranslate.translate(categories.map(i => i.name), 'en', 'fr', function(err, translations) {
translations.forEach((tr, index) => {
translatedCategories.push({
id: categories[index].id,
name: tr.translatedText
});
});
});
if you want to just change the name of your categories, this should do the trick...
function replace(categories, result) {
for (let i = 0; i < categories.length; i++) {
categories[i].name = result[i];
}
return categories;
}
have a look at the snippet, it's simple.
const categories = [
{ id: 9, name: 'General Knowledge' },
{ id: 10, name: 'Entertainment: Books' },
{ id: 11, name: 'Entertainment: Film' },
{ id: 12, name: 'Entertainment: Music' },
{ id: 13, name: 'Entertainment: Musicals & Theatres' },
{ id: 14, name: 'Entertainment: Television' },
{ id: 15, name: 'Entertainment: Video Games' },
{ id: 16, name: 'Entertainment: Board Games' },
{ id: 17, name: 'Science & Nature' },
{ id: 18, name: 'Science: Computers' },
{ id: 19, name: 'Science: Mathematics' },
{ id: 20, name: 'Mythology' },
{ id: 21, name: 'Sports' },
{ id: 22, name: 'Geography' },
{ id: 23, name: 'History' },
{ id: 24, name: 'Politics' },
{ id: 25, name: 'Art' },
{ id: 26, name: 'Celebrities' },
{ id: 27, name: 'Animals' },
{ id: 28, name: 'Vehicles' },
{ id: 29, name: 'Entertainment: Comics' },
{ id: 30, name: 'Science: Gadgets' },
{ id: 31, name: 'Entertainment: Japanese Anime & Manga' },
{ id: 32, name: 'Entertainment: Cartoon & Animations' }
]
const result = [ 'Culture générale',
'Divertissement: livres',
'Divertissement: Film',
'Divertissement: Musique',
'Divertissement: comédies musicales et théâtres',
'Divertissement: Télévision',
'Divertissement: jeux vidéo',
'Divertissement: jeux de société',
'Science et nature',
'Science: Informatique',
'Science: Mathématiques',
'Mythologie',
'Des sports',
'La géographie',
'L\'histoire',
'Politique',
'Art',
'Célébrités',
'Animaux',
'Véhicules',
'Divertissement: BD',
'Science: Gadgets',
'Divertissement: anime et manga japonais',
'Divertissement: dessin animé et animations' ];
let catNew = replace(categories, result);
console.log(catNew);
function replace(categories, result) {
for (let i = 0; i < categories.length; i++) {
categories[i].name = result[i];
}
return categories;
}
I am creating a fortune wheel using jquery and want to getting the exact number from the spinning wheel
Jquery I am using this in html
var prices = [{
name: '0'
}, {
name: '1'
}, {
name: '2'
}, {
name: '3'
}, {
name: '4'
}, {
name: '5'
}, {
name: '6'
}, {
name: '7'
}, {
name: '8'
}, {
name: '9'
}, {
name: '10'
}, {
name: '11'
}, {
name: '12'
}, {
name: '13'
}, {
name: '14'
}, {
name: '15'
}, {
name: '16'
}, {
name: '17'
}, {
name: '18'
}, {
name: '19'
}, {
name: '20'
}, {
name: '21'
}, {
name: '22'
}, {
name: '23'
}, {
name: '24'
}, {
name: '25'
}, {
name: '26'
}, {
name: '27'
}, {
name: '28'
}, {
name: '29'
}, {
name: '31'
}, {
name: '32'
}, {
name: '33'
}, {
name: '34'
}, {
name: '35'
}, {
name: '36'
}];
$(function() {
var $r = $('.roulette').fortune(prices);
var clickHandler = function() {
$('.spinner').off('click');
$('.spinner span').hide();
$r.spin().done(function(price) {
$('.price').text('You have: ' + price.name);
$('.spinner').on('click', clickHandler);
$('.spinner span').show();
});
};
$('.spinner').on('click', clickHandler);
});
I am not sure where I am going with this code. everytime its spin its give me incorrect result.Please May be I am confuse with the logic behind this spinning wheel. Please help me with this
Here is the live example of what i created so far. Please guide me what I have to do to get the accurate result
http://codepen.io/anon/pen/bWwVVj
The problem is because your prices array is in numerical order. It should be in the same order as the values in shown on the roulette wheel, like this:
var prices = [
{ name: 0 },
{ name: 26 },
{ name: 3 }
// ...
];
Updated Codepen
Also note that your array of objects with just one property is pretty redundant. You can just use an array of integers instead, like this:
var prices = [0, 26, 3, 35, 12, 28, 7, 29, 18, 22, 9, 31, 14, 20, 1, 33, 16, 24, 5, 10, 23, 8, 30, 11, 36, 13, 27, 6, 34, 17, 25, 2, 21, 4, 19, 15, 32];
Updated Codepen
What might be the easiest solution in lodash to recursively find item in array by, for example, 'text' field with value 'Item-1-5-2'?
const data = [
{
id: 1,
text: 'Item-1',
children: [
{ id: 11, text: 'Item-1-1' },
{ id: 12, text: 'Item-1-2' },
{ id: 13, text: 'Item-1-3' },
{ id: 14, text: 'Item-1-4' },
{
id: 15,
text: 'Item-1-5',
children: [
{ id: 151, text: 'Item-1-5-1' },
{ id: 152, text: 'Item-1-5-2' },
{ id: 153, text: 'Item-1-5-3' },
]
},
]
},
{
id: 2,
text: 'Item-2',
children: [
{ id: 21, text: 'Item-2-1' },
{ id: 22, text: 'Item-2-2' },
{ id: 23, text: 'Item-2-3' },
{ id: 24, text: 'Item-2-4' },
{ id: 25, text: 'Item-2-5' },
]
},
{ id: 3, text: 'Item-3' },
{ id: 4, text: 'Item-4' },
{ id: 5, text: 'Item-5' },
];
Thank You!
In plain Javascript, you could use Array#some recursively.
function getObject(array, key, value) {
var o;
array.some(function iter(a) {
if (a[key] === value) {
o = a;
return true;
}
return Array.isArray(a.children) && a.children.some(iter);
});
return o;
}
var data = [{ id: 1, text: 'Item-1', children: [{ id: 11, text: 'Item-1-1' }, { id: 12, text: 'Item-1-2' }, { id: 13, text: 'Item-1-3' }, { id: 14, text: 'Item-1-4' }, { id: 15, text: 'Item-1-5', children: [{ id: 151, text: 'Item-1-5-1' }, { id: 152, text: 'Item-1-5-2' }, { id: 153, text: 'Item-1-5-3' }, ] }, ] }, { id: 2, text: 'Item-2', children: [{ id: 21, text: 'Item-2-1' }, { id: 22, text: 'Item-2-2' }, { id: 23, text: 'Item-2-3' }, { id: 24, text: 'Item-2-4' }, { id: 25, text: 'Item-2-5' }, ] }, { id: 3, text: 'Item-3' }, { id: 4, text: 'Item-4' }, { id: 5, text: 'Item-5' }, ];
console.log(getObject(data, 'text', 'Item-1-5-2'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
It's the perfect spot for a recursive function.
function findText(items, text) {
if (!items) { return; }
for (const item of items) {
// Test current object
if (item.text === text) { return item; }
// Test children recursively
const child = findText(item.children, text);
if (child) { return child; }
}
}
That's also the best way to get the maximum performances. Traversal is some in depth-first-search way.
I need to merge two json object based on key value using javascript.
I have two different variable g and c.
terms: All values need to merge.
var g = [ { id: 36, name: 'AAA', goal: 'yes' },
{ id: 40, name: 'BBB', goal: 'yes' },
{ id: 57, name: 'CCC', goal: 'yes' },
{ id: 4, name: 'DDD', goal: 'yes' },
{ id: 39, name: 'EEE', goal: 'yes' },
{ id: 37, name: 'FFF', goal: 'yes' },
{ id: 59, name: 'GGG', goal: 'yes' },
{ id: 50, name: 'III', goal: 'yes' },
{ id: 43, name: 'HHH', goal: 'yes' },
{ id: 35, name: 'JJJ', goal: 'yes' } ]
var c = [ { id: 36, name: 'AAA', circle: 'yes' },
{ id: 40, name: 'BBB', circle: 'yes' },
{ id: 57, name: 'CCC', circle: 'yes' },
{ id: 42, name: 'ZZZ', circle: 'yes' },
{ id: 4, name: 'DDD', circle: 'yes' },
{ id: 39, name: 'EEE', circle: 'yes' },
{ id: 37, name: 'FFF', circle: 'yes' },
{ id: 59, name: 'GGG', circle: 'yes' },
{ id: 43, name: 'HHH', circle: 'yes' },
{ id: 35, name: 'JJJ', circle: 'yes' },
{ id: 100, name: 'JJJ', circle: 'yes' } ]
I tried the following code: but i merge what are have same id in 'c' variable. but i need to merge compare 'g' and 'c'.
var arrayList = [];
for(var i in g) {
var getid = g[i].id;
var getname = g[i].name;
var getgoal = g[i].goal;
for(var j in c){
var compareid = c[j].id;
if(getid == compareid){
var obj = {};
obj.id = getid;
obj.name = getname;
obj.goal = 'yes';
obj.circle = 'yes';
console.log(obj);
arrayList.push(obj);
}
}
}
console.log(arrayList);
Expected output:
[ { id: 36, name: 'AAA', goal: 'yes',circle: 'yes' },
{ id: 40, name: 'BBB', goal: 'yes',circle: 'yes' },
{ id: 57, name: 'CCC', goal: 'yes',circle: 'yes' },
{ id: 4, name: 'DDD', goal: 'yes' ,circle: 'yes' },
{ id: 39, name: 'EEE', goal: 'yes' ,circle: 'yes' },
{ id: 37, name: 'FFF', goal: 'yes' ,circle: 'yes'},
{ id: 59, name: 'GGG', goal: 'yes' ,circle: 'yes'},
{ id: 50, name: 'III', goal: 'yes' ,circle: 'no'},
{ id: 43, name: 'HHH', goal: 'yes' ,circle: 'yes'},
{ id: 35, name: 'JJJ', goal: 'yes' ,circle: 'yes'} ,
{ id: 42, name: 'ZZZ', goal: 'no' , circle: 'yes' },
{ id: 100, name: 'JJJ',goal: 'no' , circle: 'yes' }]
You forgot to push obj in the first loop in case the id doesn't exist in c and to loop through c in case one or more id's of that object does not exist in g.
var g = [
{ id: 36, name: 'AAA', goal: 'yes' },
{ id: 40, name: 'BBB', goal: 'yes' },
{ id: 57, name: 'CCC', goal: 'yes' },
{ id: 4, name: 'DDD', goal: 'yes' },
{ id: 39, name: 'EEE', goal: 'yes' },
{ id: 37, name: 'FFF', goal: 'yes' },
{ id: 59, name: 'GGG', goal: 'yes' },
{ id: 50, name: 'III', goal: 'yes' },
{ id: 43, name: 'HHH', goal: 'yes' },
{ id: 35, name: 'JJJ', goal: 'yes' }
],
c = [
{ id: 36, name: 'AAA', circle: 'yes' },
{ id: 40, name: 'BBB', circle: 'yes' },
{ id: 57, name: 'CCC', circle: 'yes' },
{ id: 42, name: 'ZZZ', circle: 'yes' },
{ id: 4, name: 'DDD', circle: 'yes' },
{ id: 39, name: 'EEE', circle: 'yes' },
{ id: 37, name: 'FFF', circle: 'yes' },
{ id: 59, name: 'GGG', circle: 'yes' },
{ id: 43, name: 'HHH', circle: 'yes' },
{ id: 35, name: 'JJJ', circle: 'yes' },
{ id: 100, name: 'JJJ', circle: 'yes' }
],
arrayList = [], obj_c_processed = [];
for (var i in g) {
var obj = {id: g[i].id, name: g[i].name, goal: g[i].goal};
for (var j in c) {
if (g[i].id == c[j].id) {
obj.circle = c[j].circle;
obj_c_processed[c[j].id] = true;
}
}
obj.circle = obj.circle || 'no';
arrayList.push(obj);
}
for (var j in c){
if (typeof obj_c_processed[c[j].id] == 'undefined') {
arrayList.push({id: c[j].id, name: c[j].name, goal: 'no', circle: c[j].circle});
}
}
console.log(arrayList);
Using undescore.js, you can write some function like this:
var a = [ { id: 36, name: 'AAA', goal: 'yes' },
{ id: 40, name: 'BBB', goal: 'yes' },
{ id: 57, name: 'CCC', goal: 'yes' },
{ id: 4, name: 'DDD', goal: 'yes' },
{ id: 39, name: 'EEE', goal: 'yes' },
{ id: 37, name: 'FFF', goal: 'yes' },
{ id: 59, name: 'GGG', goal: 'yes' },
{ id: 50, name: 'III', goal: 'yes' },
{ id: 43, name: 'HHH', goal: 'yes' },
{ id: 35, name: 'JJJ', goal: 'yes' } ];
var b = [ { id: 36, name: 'AAA', circle: 'yes' },
{ id: 40, name: 'BBB', circle: 'yes' },
{ id: 57, name: 'CCC', circle: 'yes' },
{ id: 42, name: 'ZZZ', circle: 'yes' },
{ id: 4, name: 'DDD', circle: 'yes' },
{ id: 39, name: 'EEE', circle: 'yes' },
{ id: 37, name: 'FFF', circle: 'yes' },
{ id: 59, name: 'GGG', circle: 'yes' },
{ id: 43, name: 'HHH', circle: 'yes' },
{ id: 35, name: 'JJJ', circle: 'yes' },
{ id: 100, name: 'JJJ', circle: 'yes' } ];
function merge_object_arrays (arr1, arr2, match) {
return _.union(
_.map(arr1, function (obj1) {
var same = _.find(arr2, function (obj2) {
return obj1[match] === obj2[match];
});
return same ? _.extend(obj1, same) : obj1;
}),
_.reject(arr2, function (obj2) {
return _.find(arr1, function(obj1) {
return obj2[match] === obj1[match];
});
})
);
}
document.getElementsByTagName('pre')[0].innerHTML = JSON.stringify(
merge_object_arrays(a, b, 'id'), null, 2
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<pre>
</pre>
Try running it here.
Try using jquery. Try this :
var g= [
{ id: 36, name: 'AAA', goal: 'yes' },
{ id: 40, name: 'BBB', goal: 'yes' },
{ id: 57, name: 'CCC', goal: 'yes' },
{ id: 4, name: 'DDD', goal: 'yes' },
{ id: 39, name: 'EEE', goal: 'yes' },
{ id: 37, name: 'FFF', goal: 'yes' },
{ id: 59, name: 'GGG', goal: 'yes' },
{ id: 50, name: 'III', goal: 'yes' },
{ id: 43, name: 'HHH', goal: 'yes' },
{ id: 35, name: 'JJJ', goal: 'yes' } ];
var c= [
{ id: 36, name: 'AAA', circle: 'yes' },
{ id: 40, name: 'BBB', circle: 'yes' },
{ id: 57, name: 'CCC', circle: 'yes' },
{ id: 42, name: 'ZZZ', circle: 'yes' },
{ id: 4, name: 'DDD', circle: 'yes' },
{ id: 39, name: 'EEE', circle: 'yes' },
{ id: 37, name: 'FFF', circle: 'yes' },
{ id: 59, name: 'GGG', circle: 'yes' },
{ id: 43, name: 'HHH', circle: 'yes' },
{ id: 35, name: 'JJJ', circle: 'yes' },
{ id: 100, name: 'JJJ', circle: 'yes' } ];
var combine_obj={};
$.extend(combine_obj, g, c);
OR using simple javascript
var combine_obj={};
for(var key in g) combine_obj[key]=g[key];
for(var key in c) combine_obj[key]=c[key];
You could do it like this,
var g = [ { id: 36, name: 'AAA', goal: 'yes' },
{ id: 40, name: 'BBB', goal: 'yes' },
{ id: 57, name: 'CCC', goal: 'yes' },
{ id: 4, name: 'DDD', goal: 'yes' },
{ id: 39, name: 'EEE', goal: 'yes' },
{ id: 37, name: 'FFF', goal: 'yes' },
{ id: 59, name: 'GGG', goal: 'yes' },
{ id: 50, name: 'III', goal: 'yes' },
{ id: 43, name: 'HHH', goal: 'yes' },
{ id: 35, name: 'JJJ', goal: 'yes' } ]
var c = [ { id: 36, name: 'AAA', circle: 'yes' },
{ id: 40, name: 'BBB', circle: 'yes' },
{ id: 57, name: 'CCC', circle: 'yes' },
{ id: 42, name: 'ZZZ', circle: 'yes' },
{ id: 4, name: 'DDD', circle: 'yes' },
{ id: 39, name: 'EEE', circle: 'yes' },
{ id: 37, name: 'FFF', circle: 'yes' },
{ id: 59, name: 'GGG', circle: 'yes' },
{ id: 43, name: 'HHH', circle: 'yes' },
{ id: 35, name: 'JJJ', circle: 'yes' },
{ id: 100, name: 'JJJ', circle: 'yes' } ]
for (i = 0; i < g.length; i++) { //Loop trough first array
var curID = g[i].id; //Get ID of current object
var exists = false;
for (j = 0; j < c.length; j++) { //Loop trough second array
exixts = false;
if (curID == c[j].id){ //If id from array1 exists in array2
exixts = true;
tempObj = c[j]; //Get id,object from array 2
break;
}
}
if(exixts) {
g[i]["circle"] = tempObj.circle;//If exists add circle from array2 to the record in array1
}else{
g[i]["circle"] = "no"; //If it doesn't add circle with value "no"
}
}
for (i = 0; i < c.length; i++) { //Loop trough array 2
var curObj = c[i];
var ex = true;
g.forEach(function(row) { //Loop to check if id form array2 exists in array1
if (curObj.id == row.id){
ex = false;
}
});
if(ex){ //If it doesn't exist add goal to object with value "no" and push it into array1
curObj["goal"] = "no";
g.push(curObj);
}
}
console.debug(g);
I've added some comments to explain what is going on in the code.
Psuedo code,
//Loop trough g
//get id from g[i] and check if it exists in c
//if so
//add circle from a2 to a1[i]
//Add value of circle from c onto g[i]["circle"]
//otherwise
//Add value of "no" onto g[i]["circle"]
//Loop trough c
//If id isn't in g, add row with value c[i]["goal"] = "no" to g