This question already has answers here:
Using Javascript loop to create multiple HTML elements
(3 answers)
Closed 2 years ago.
I want to create a new img Element in javascript when my forEach loop read any index of my array and this is the code
axios.get('https://jsonplaceholder.typicode.com/photos', {params: {_limit: 20}}).then(res => {
let values = Object.values(res);
values[0].forEach((item) => {
document.getElementById('root').innerHTML = `<img src="${item.url}">`;
}
})
I thought I would do a runnable version based on Mr Alien's (now deleted) answer. However, as pointed out by Vektor's comment this is likely not helpful (or at least not ideal) if you're working in something like React.
If you are working in something like React you would more likely want to setup state for the images array, render the images based on this array and setup something like a useEffect hook / componentDidMount method to load the images and update the state.
Runnable version based on Mr Alien's (now deleted) answer:
const ele_with_attributes = (tag, attributes = {}) =>
Object.assign(document.createElement(tag), attributes);
const append_image_from_api = (item) =>
document.getElementById('images').appendChild(
ele_with_attributes('img', {
src: item.thumbnailUrl, //item.url,
alt: item.title
})
);
axios
.get('https://jsonplaceholder.typicode.com/photos', {params: {_limit: 5}})
.then(res => res?.data?.forEach(append_image_from_api));
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
<div id="images"></div>
Related
This question already has answers here:
How to create an HTML table from an array of objects?
(2 answers)
Closed 19 days ago.
I am new and not afraid of working on a problem and I'm grateful for all the knowledge available. But I have tried and failed for too long now.
// 1. GET request using fetch()
fetch("https://jsonplaceholder.typicode.com/todos")
// Convert received data to JSON
.then(response => response.json())
.then(users => show(users));
function show(users) {
const para = document.querySelector("p");
for (let user of users) {
let html = `<p>${user.title}</p>`;
para.insertAdjacentHTML("afterend", html);
}
};
<ul> <!-- loop start -->
<li>
<img src="https://picsum.photos/200" />
<p></p> <!-- append to <p>${users.title}</p> for each obj -->
</li>
</ul> <!-- loop end -->
Of course that will loop the P tag with user.title for each json object. But that's as far as I get... lots of successful variations though building a new list.
I keep going back to thinking I'm close with something like:
Array.from(document.querySelectorAll('p'))
.forEach(p => {
p.innerHTML = p.innerHTML
.replace();
})
But I just am not sure and cant get it even close enough to know I may be on the right track. I know the replace() method isn't right, and 'replaceWith()' is Jquery... is this where the show function woudl run? I keep coming back to this as I did something similar in a tutorial and it seems frustratingly close.
I'm not asking anyone to do it for me 'cause then I won't learn but even a hint would be inspiring enough to drive me to invest countless more hours. Still, beats the other sh!t I could be doing at my age, like sleeping. Cheers ~
Use document.createElement to make <li> elements to add to the unordered list with Element#append.
fetch("https://jsonplaceholder.typicode.com/todos")
.then(response => response.json())
.then(users => show(users));
function show(users) {
const ul = document.querySelector('ul');
for (const user of users) {
const li = document.createElement('li');
const p = document.createElement('p');
p.textContent = user.title;
li.append(p);
ul.append(li);
}
}
<ul></ul>
You can use the template element to create a template of the entire html snippet you want in your loop.
Then, in your loop, create a clone of that template, update the parts you want to update, and append to the ul element.
// 1. GET request using fetch()
fetch("https://jsonplaceholder.typicode.com/todos")
// Convert received data to JSON
.then(response => response.json())
.then(users => show(users));
function show(users) {
// get target list
const list = document.querySelector('ul');
for (let user of users) {
// clone your template
const templateClone = document.querySelector('#listItemTemplate').content.cloneNode(true);
// insert user title into paragraph element of cloned template
templateClone.querySelector('p').innerText = user.title;
// append to end of the list
list.appendChild(templateClone);
}
};
<ul>
</ul>
<template id="listItemTemplate">
<li>
<img src="https://picsum.photos/200" />
<p></p>
</li>
</template>
I currently have the following code that lists a list of years. I feel that all this code may be very unnecessary and perhaps a computed property for validYears, would help me make this code more optimal and get rid of the unnecessary watchers. My issue is converting this to a computed property as I'm failing to grasp the correct logic to achieve this. I'd appreciate if someone can offer an example of how I can set a computed property for valid years and still return the same result.
onBeforeMount(calculateDateRange)
watch(() => props.earliestDate, (newValue, prevValue) => {
calculateDateRange();
});
// If there is a new value passed from the parent, the dropdown should display that new value.
watch(() => props.latestDate, (newValue, prevValue) => {
calculateDateRange()
});
const validYears = ref([])
function calculateDateRange () {
for(let year = props.latestDate; year >= props.earliestDate; year--){
validYears.value.push(year)
}
}
I didn't provide the rest of the code not to clutter the question, but as one can see in this component I have a set of props that determine the values in my for loop.
You could optimize it as follows :
const validYears = computed(()=>{
let _years=[]
for(let year = props.latestDate; year >= props.earliestDate; year--){
_years.push(year)
}
return _years;
})
getLinksByElementAttribute = async (element, attribute) => { /**#type{array}*/ let arrayHTML = [];
return new Cypress.Promise((resolve) => {
cy.get(element).each(($el, index) => {
//cy.log();
arrayHTML[index] = $el.attr(attribute);
resolve(arrayHTML);
});
cy.log(arrayHTML)
});
}
}
I am passing 'a' tag as element and 'href' as attribute and would like to have all the links on webpage which I got using arrayHTML[index] stored in an array together, any help on how to store the links together and return them as one array ?
When I currently run the code then I see the cy.log return value 'Array[52]' in log file for my weblink,means I have 52 'a' elements on my web page, any idea on how I can see actual values of 52 found elements?
That happens because of the asynchronous behavior of cypress. One solution could be to use cy.wrap() and JSON.stringify():
cy.wrap(arrayHTML)
.then((array) => cy.log(JSON.stringify(array)));
More information here: https://docs.cypress.io/guides/core-concepts/introduction-to-cypress#Mixing-Async-and-Sync-code
I developing a simple chat applicaiton for my website using firebase firestore. where every chat session has an id
provided i have an array of ids
chat_sessions = ["q93XhadA9QQLu6X8yfZB", "YXEYISEI8b2iixCcP3VO", "GXrSZbtrmN5NcrtvjFYp"]
I want to get all document whose id is equal to any of the id's in the chat_sessions object using the code below.
return this.afs
.collection('chats', ref => ref.where('uid','in_array',chat_sessions)).snapshotChanges...
but I am not getting any results.
I come from a PHP/MYSQL background
the PHP equivalent of what i am trying to achieve will be sth like this in PHP
if(in_array(uid,chat_sessions)){
get(doc/uid)
}
can anyone help with the right query where we check for document id against a list of ids in an array? Thank You!
Thank you #frank van Puffelen. You were almost right. I should have used in instead of in_array
ref.where(firebase.firestore.FieldPath.documentId(),'in_array',chat_sessions)
did not work. Instead I replaced in_array with in :
ref.where(firebase.firestore.FieldPath.documentId(),'in',chat_sessions)
This worked! Thank you
Your query is:
ref.where('uid','in_array',chat_sessions)
This checks a field called uid in each document against the values of the chat_sessions.
It seems that instead you want to the check the ID of each document against the array, which you can do with:
ref.where(firebase.firestore.FieldPath.documentId(),'in_array',chat_sessions)
I found something else on firestore i.e "array-contains-any" for this case.
Maybe it's updated now.
UPDATE
Hi, firebase did some update recently, so for do it I found out this method
`
const [products, setProduct] = useState([]);
const ids = ['H11LlJsh3sObwORZhA0b','om9m0lU9HYWyOJZKvEdi','1AoHyHuSFcF01zoyXyTD','6xoBlxsRXUoyzBUcWl0F',
'GJqthlmBGZaFAJqtC2jK','QNT3PxMfhNGg1RZnuqcq','RZgGoFZHyDAYaVZJWxGk','g4UO5P0EgtEqJnawwhXX','gyrZm8p0cEgJdDvTuB1g','mrscldfeYlkaSF151MpI',]
useEffect(() => {
const saveFirebaseTodos = [];
ids.forEach((element) => {
fetchMyAPI()
async function fetchMyAPI() {
const q = query(collection(db, "a"), where('__name__', '==', element));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
saveFirebaseTodos.push(({id: doc.id, ...doc.data()}));
/*console.log(doc.id, " => ", doc.data());*/
if (ids.length == saveFirebaseTodos.length) {
setProduct(saveFirebaseTodos)
}
});
}})
}, [])`
In this way, you can check how many element in arrays you want (bypassing 10 elements limit of firebase).
Hope can help anyone :D
This question already has answers here:
How to render an array of objects in React?
(6 answers)
Closed 4 years ago.
I am getting the response from an api in this way
data:Array(3)
0:"new"
1:"ruby"
2:"ruby"
I want to display this data under a tr element inside a jsx expression. I made a loop to traverse through the array like this
let course = [];
let userid = this.props.match.params.userid;
axios.get("someapi") //the api to hit request
.then((response) => {
console.log(response);
for (var i = 0; i < response.data.length; i++) {
console.log(response.data[i]);
course.push(response.data[i]);
}
console.log("course", course);
this.setState({ course: course });
console.log("state course", this.state.course);
});
I am getting all the values in both console.log, with "course" and "state course" but can't map it inside tbody to display it in tr tag. I want to render it inside this
<tbody>
<tr>new,ruby and ruby should be displayed here as a list</tr>
</tbody>
What am i doing wrong?
Inside of your table
<tbody>
{this.state.course.map(ele =>
<tr>{ele}</tr>
)}
</tbody>
this should work.
You can also refer to React doc's section: List and Key.
If you want all three courses inside the same <tr> tag as a list you could try:
let course = [];
let userid = this.props.match.params.userid;
axios.get("someapi") //the api to hit request
.then((response) => {
console.log(response);
course = response.data.join(", ");
console.log("course", course);
this.setState({ course: course });
console.log("state course", this.state.course);
});
Then use the course variable in your jsx inside the <tr> tag.
If you want to print one tr for each course set courses equal to response.data and map through it in your jsx