I am wondering how can I add data content inside array to innerHTML using the forEach?
For some reason, It is not showing up. Is this possible to do? I am working with dynamic data this way I need to loop through my data and show them with innerHTML.
const showPosts = (data, value) => {
const btnDiscover = document.querySelector('[data-show="discover"]');
const slides = data.add_post_slides;
const Posts = () => {
slides.length > 0 &&
slides
.forEach((el) => {
return <h2>123</h2>;
})
.join('');
};
// console.log(Posts());
btnDiscover.addEventListener('click', (e) => {
e.preventDefault();
body.classList.add('toggle-legend', 'no-scroll');
console.log('Discover clicked');
console.log(slides);
theContent = `
<div class="modal">
<div class="modal__body">
<span class="modal__close"></span>
${Posts()}
</div>
</div>
`;
timelineModal.innerHTML = theContent;
onModalClose();
});
};
How can I do such a thing?
There are many way. I can suggest pick the element by using getElementById. After that create a function that will add the data in innerHtml of that element. Try to do something similar below
var fruits = ["apple", "orange", "cherry"];
fruits.forEach(myFunction);
function myFunction(item, index) {
document.getElementById("demo").innerHTML += index + ":" + item + "<br>";
}
forEach don't return responses. use Array.map or declare and initialize array variables and then push them.
const newSlides = slides.map((el) => el)
or
const elements = [];
slides.forEach((el) => elements.push(el));
// Add return. your arrow function don't return element.
const Posts = () => {
return slides.length > 0 &&
slides
.forEach((el) => {
return <h2>123</h2>;
})
.join('');
};
Related
I'm building a dynamic list of trees that starts with Oak, Pine, Aspen, Bald Cypress.
Which includes a button to add a 'Redwood' tree to the end of the list, and a 'Pear' tree to the start of the list.
I then included a button that onclick would change the strings to lowercase but I can't seem to get it right. I know the push() method will add the lowercase strings to the end of the list but I can't figure out how to get rid of the old strings with uppercase letters, and it also keeps adding more items to the list when the button is pushed again. I also tried the map method, however it did not seem to work unless created a new variable.
const trees = ['Oak', 'Pine', 'Aspen', 'Bald Cypress']
const listTrees = () => {
let treeList = ''
trees.forEach(tree => {
//console.log(tree)
treeList += `${tree} <br>`
})
displayResults.innerHTML = `${treeList} <span>${trees.length} elements
long</span>`
}
listTrees()
* ------adding redwood to the end ------------*/
document.querySelector('#add_redwood').onclick = () => {
trees.push('Redwood')
listTrees()
}
/* --------------------adding a pear to the start ----------------------*/
document.querySelector('#add_pear').onclick = () => {
trees.unshift('Pear')
listTrees()
}
document.querySelector('#lowerTrees').onclick = () => {
trees.forEach(tree => {
trees.push(tree.toLowerCase())
})
listTrees()
}
Simply declare trees with let instead of const then reassign it. There is no reason for you to keep the original array reference in this case. Then you can use map(). You can also use map() for listTrees().
const displayResults = document.querySelector("#displayResults");
let trees = ['Oak', 'Pine', 'Aspen', 'Bald Cypress']
const listTrees = () => {
let treeList = trees.map(tree => `${tree}<br>`).join("");
displayResults.innerHTML = `${treeList} <span>${trees.length} elements long</span>`
}
listTrees()
/* ------adding redwood to the end------------ */
document.querySelector('#add_redwood').onclick = () => {
trees.push('Redwood')
listTrees()
}
/* --------------------adding a pear to the start ----------------------*/
document.querySelector('#add_pear').onclick = () => {
trees.unshift('Pear')
listTrees()
}
document.querySelector('#lowerTrees').onclick = () => {
trees = trees.map(tree => tree.toLowerCase());
listTrees();
}
<button id="add_redwood">Add Redwood</button>
<button id="add_pear">Add Pear</button>
<button id="lowerTrees">Lower Trees</button>
<div id="displayResults"></div>
If you really want to keep tree as const, use a regular for loop to change each element one by one instead.
for(let i = 0; i < trees.length; i++)
{
trees[i] = trees[i].toLowerCase();
}
Because you have to reassign lowercased values to HTML
document.querySelector('#lowerTrees').onclick = () => {
trees.forEach(tree => {
trees.push(tree.toLowerCase())
})
listTrees()
}
I have a list of expenses, I want to create a html code to iterate over all the expenses and show their name. I am not working with the DOM, I literally want to save the html code in a variable, so I can generate a pdf file with it.
This is what I tried:
lets say I have this array
const spents = [{expenseName: "Pizza"},{expenseName: "Home"}]
const testHtml = () => {
for(let i of spents) {
const title = `<h1>${i.expenseName}</h1>`
}
}
testHtml()
This is the result I want, something like:
htmlResult = "<h1>${i.expenseName}</h1> <h1>${i.expenseName}</h1>"
by the way, This is for a react native app.
I think this will work for you.
const spents = [{expenseName: "Pizza"},{expenseName: "Home"}]
const testHtml = () => {
let title = '';
for(let i of spents) {
title += `<h1>${i.expenseName}</h1>`
}
return title;
}
testHtml()
You could use Array.prototype.reduce().
const spents = [{
expenseName: "Pizza"
}, {
expenseName: "Home"
}];
const result = spents.reduce((prev, curr, index) => index === 0 ? curr.expenseName : `<h1>${prev}</h1> <h1>${curr.expenseName}</h1>`, '');
document.body.append(result);
I am new to JavaScript. I have a small code that creates list from input and then adds it to an array. I am able to remove one item from the DOM when the item is clicked, but I couldn't remove it from the array.
I tried to use array.splice(item, 1)
lists.addEventListener("click", function (e) {
e.target.closest("li").remove();
userInputArr.splice(item, 1);});
But it removes the entire array sometime, and sometime removes the last item. when I console log the code, it looks like I clicked 3 or 4 times on the list even though I just clicked once. I have no idea what's wrong. this is the entire code:
const lists = document.querySelector(".lists");
const userInput = document.querySelector(".add-note");
const addBtn = document.querySelector(".add-btn");
const item = document.querySelectorAll(".list");
userInputArr = [];
function addNote() {
if (userInput.value < 1) {
return;
}
lists.insertAdjacentHTML(
"afterbegin",
`<li class='list'>${userInput.value}</li>`
);
userInputArr.push(lists);
lists.addEventListener("click", function (e) {
e.target.closest("li").remove();
userInputArr.splice(item, 1);
});
userInput.value = "";
}
addBtn.addEventListener("click", function () {
addNote();
});
Code is totally meaningless
1)
userInputArr.push(lists)
why you push the same element all the time? As lists refers to the first and the only element with class 'lists'?
2)
userInputArr.splice(item, 1)
please watch carefully what splice does? The first argument is number, but you pass a collection of elements with class 'list'. But i camn not even suggest which element should be removed as it contains the same element as i mentioned in first point
3) You do not need this array at all
So right approach is something like this
const lists = document.querySelector(".lists");
// just once create listener, no need to do it each time
lists.addEventListener("click", function (e) {
// if you want to remove clicked item then
if (e.target.tagName === 'LI') e.target.remove();
// but if you want to remove the first one then uncomment line
// if (this.children[0]) this.children[0].remove()
});
const userInput = document.querySelector(".add-note");
const addBtn = document.querySelector(".add-btn");
///////////////////////////////////////////////////
// item is meaninglee here, so delete this line
// const item = document.querySelectorAll(".list");
//////////////////////
// array is useless too, delete this line
// userInputArr = [];
function addNote() {
// check if it is number
if (isNaN(userInput.value) || Number(userInput.value < 1)) {
return;
}
lists.insertAdjacentHTML(
"afterbegin",
`<li class='list'>${userInput.value}</li>`
);
userInput.value = "";
}
addBtn.addEventListener("click", function () {
addNote();
});
const items = (() => {
const _items = {};
let key = 0;
return {
put(value) {
_items[key++] = value;
console.log("Added", this.all());
return key - 1;
},
remove(key) {
delete _items[key++];
console.log("Removed", this.all());
},
all(asArray = true) {
return asArray ? Object.values(_items) : { ..._items
};
}
}
})();
const inputEl = document.querySelector(".input");
const itemsEl = document.querySelector(".items");
const addBtn = document.querySelector(".btn-add");
addBtn.addEventListener("click", () => {
const value = inputEl.value.trim();
if (!value.length) return;
const key = items.put(value);
const li = document.createElement("li");
li.textContent = value;
li.dataset.key = key;
itemsEl.append(li);
inputEl.value = "";
});
itemsEl.addEventListener("click", (e) => {
const li = e.target.closest("li");
items.remove(li.dataset.key);
li.remove();
});
<input type="text" class="input">
<button class="btn-add">Add</button>
<ul class="items"></ul>
Run code & View in full screen.
use shift() userInputArr.shift()
you are also getting double clicks because your addNote() function contains an event listener lists.addEventListener and it's executed by another event listner addBtn.addEventListener you should probably move
lists.addEventListener out of the addNote function
I am trying to find index of array using lodash locationbar. but my react console showing some warnings. can be resolve?
let wishListData = wishList.result;
let j = 0; const jMax = wishListData.length;
for (; j < jMax; j++) {
var index = _.findIndex(products.result, function (product) {
return product.id === wishListData[j]['pid']
});
if (index !== -1) {
products.result[index]['isWishList'] = true;
}
}
Iterate over wishList.result with forEach instead of a for loop, and you'll avoid the warning:
wishListData.forEach(({ pid }) => {
const index = _.findIndex(products.result, ({ id }) => id === pid);
if (index !== -1) {
products.result[index].isWishList = true;
}
});
Note that this is a linter warning, not a Javascript error. Your code works, the linter just considers it to be confusing - better to use array methods instead of loops when possible.
Also, feel free to remove the _ library and just use built-in Javascript methods instead, if you want:
wishListData.forEach(({ pid }) => {
const product = products.result.find(({ id }) => id === pid);
if (product) {
product.isWishList = true;
}
});
Or, for an O(N) solution instead of an O(N^2) solution, figure out all pids first, then iterate over the products:
const pids = new Set(wishListData.map(({ pid }) => pid));
products.result.forEach((product) => {
if (pids.has(product.id)) {
product.isWishList = true;
}
});
You can try something like this as well:
Instead of mutating product in products.result[index]['isWishList'] = true;, you should create new object to minimize side-effect.
Also, instead of looping on wishListData, you can create a list of PIDs and just check index. If this list is created outside, you can create list of PIDs outside as well. That will reduce processing it every time
const wishListPID = wishList.result.map((x) => x.pid);
const result = products.result.map((product) => {
const isWishList = wishListPID.indexOf(product.id) !== -1;
return { ...product, isWishList }
});
i wanted to remove an element from an array but i'm not getting, my code is:
const renderCount = state => {
const peopleHtml = state.filteredPeople.map(person => {
const personHtml = document.createElement('LI');
const personName = document.createTextNode(person.name);
const buttonDelete = document.createElement('Button');
const textOfButtonDelete = document.createTextNode('Delete');
buttonDelete.appendChild(textOfButtonDelete);
personHtml.appendChild(personName);
personHtml.appendChild(buttonDelete);
buttonDelete.onclick = function() {
return {...state,filteredPeople : state.filteredPeople.filter( (item, index) => index !=="Jean")}
}
return personHtml;
});
resultado.innerHTML = '';
peopleHtml.forEach(personHtml => resultado.appendChild(personHtml));
};
export default renderCount;
What the code makes?
He renders the elements of an array, 3 in 3. Each element of array have a button 'delete'and each time that i clicked that, a element get out off the screen.
The code and the button are: buttonDelete.onclick.....
Thanks and good afternoon.
This is not the right way to do in reactjs. React believe on Virtual DOM. Your states values and HTML elements will be talking with each other and you do not need to use appendChild or removeChild to update them , just update the state value. Some thing like below
render()
{
return (
<div>
<ul>
{this.state.filteredPeople.map(person => { =>
<li>
{person.name}
<button onClick={this.deleteme.bind(this,person.id)}>Delete</button>
</li>
)}
</ul>
</div>
);
}
deleteme(index){
let initial_val = this.state.contents.slice();
let obj_to_del= initial_val.find(person => person.id === id);
initial_val.remove(obj_to_del);
this.setState({people:initial_val});
}