So, i got everything almost working as i want it, just a mistake that im struggling. Everytime i search for an item, when the result for that item shows the length is repeated.
When i search for ox there are 2 results and that is correct, but the length (2) shows in both of them, i only display one
[Code]
const resultHtml = (itemsMatch) => {
if (itemsMatch.length > 0) {
const html = itemsMatch
.map(
(item) => `
<span>${itemsMatch.length}</span>
<div class="card">
<div class="items-img">
</div>
<div class="items-info">
<h4>${item.title}</h4>
<small>${item.path}</small>
</div>
</div>
`
)
.join('');
//console.log(html);
itemList.innerHTML = html;
}
};
////
Question 2
I got one more question, i was trying to get the image from the Json and what i got was the path haha
why the apth and not the img
const resultHtml = (itemsMatch) => {
if (itemsMatch.length > 0) {
const html =
`<span class="items-results">${itemsMatch.length} Resultados</span>` +
itemsMatch
.map(
(item) => `
<div class="card">
<div class="items-img">
${item.image}
</div>
<div class="items-info">
<h4>${item.title}</h4>
<small>${item.path}</small>
</div>
</div>
`
)
.join('');
console.log(html);
itemList.innerHTML = html;
}
};
If you move <span>${itemsMatch.length}</span> out of your map callback, it will not repeat for each item. Read more about map() here.
Replace:
const html = itemsMatch
.map(
(item) => `
<span>${itemsMatch.length}</span>
... more HTML here
`
)
.join('');
With this:
const html = `<span>${itemsMatch.length}</span>` + (
itemsMatch
.map(
(item) => `
<div class="card">
<div class="items-img">
</div>
<div class="items-info">
<h4>${item.title}</h4>
<small>${item.path}</small>
</div>
</div>
`
)
.join('')
);
Regarding your image issue:
You are just outputting the path and that's why it's printing out just the path. If you are trying to display an image then put the path as source of <img> tag.
So, instead of just:
${item.image}
Use:
<img src="${item.image}">
Related
I have an array that I am iterating over with forEach and I need to add what is output to the console in html using template strings. How can i do this?
const postCategories = arr[index].category;
const postCategory = postCategories.forEach(category => {
console.log(category.name);
});
const article = `<article class="news">
<div class="news-taxonomy">
<span>//Here I need to enter the name of the category</span>
</div>
</article>`;
.forEach returns undefined, .map will return to you a result you're after.
I'm going to assume that each category contains at least a name key...
Additionally, I'm assuming you want to insert the result of that at the end of all the iterations
const postCategories = arr[index].category;
const postCategory = postCategories.map(category => {
return `<div>${category.name}</div>`;
});
const article = `
<article class="news">
<div class="news-taxonomy">
${postCategory}
</div>
</article>
`;
Note: This is my preferred format for multiline strings using "` `.
The output would be something like this:
<article class="news">
<div class="news-taxonomy">
<div>Category 1</div>
<div>Second Category</div>
<div>Category 3</div>
</div>
</article>
You just need to inject in the body with insertAdjacentHTML.
beforeend means just before the body end tag.
const postCategories = ['one', 'two', 'three']
const postCategory = postCategories.forEach(category => {
const template = `<article class="news">
<div class="news-taxonomy">
<span>${category}</span>
</div>
</article>`
document.body.insertAdjacentHTML('beforeend', template)
});
So, I am trying to pull the volume info from the JSON array from the URL provided: https://www.googleapis.com/books/v1/volumes?q=HTML5
Trying to pull author, title, images, page numbers and description.
This specific class of my HTML code I want to put the JSON data that I have mentioned above in is the 'b-card' class:
<div class="booklist">
<div class="booklist-cards">
<div class="b-card">
</div>
<div class="b-card">
</div>
<div class="b-card">
</div>
<div class="b-card">
</div>
<div class="b-card">
</div>
<div class="b-card">
</div>
<div class="b-card">
</div>
<div class="b-card">
</div>
</div>
</div>
<script src="https://www.googleapis.com/books/v1/volumes?q=HTML5"></script>
<script src="assets/js/script.js"></script>
The script.js file I have tried is below:
function handleResponse(obj) {
const book = Objects.keys(obj).map(item => obj['items']).reduce(
(acc, rec, id, array) => {
let singleBookCover = rec[id].volumeInfo.imageLinks.thumbnail;
let singleBookTitle = rec[id].volumeInfo.title;
let singleBookAuthor = rec[id].volumeInfo.authors[0];
return [...acc, {singleBookCover, singleBookTitle, singleBookAuthor}]
},
[]
).forEach( item => {
let title = document.createElement('h1');
title.textContent = `${item.singleBookTitle}`;
let author = document.createElement('strong');
author.textContent = `${item.singleBookAuthor}`;
let img = document.createElement('img');
img.src = item.singleBookCover;
img.alt = `${item.singleTitle} by ${item.singleBookAuthor}`;
let container = document.getElementsByClassName('b-card');
container.appendChild(title).appendChild(author).appendChild(img);
})
return book
}
The above code only adds the title image and author, but I cant get them to load into my HTML.
What are ways to resolve this? Am i calling the URL correctly in the HTML script tag?
Forgot to mention - would like to achieve this without using JQuery & AJAX. I have also tried inputting the callback to handleResponse in the script tag url but it doesnt work.
you can't append to the HTML because container is array so it need index of the element
container[index].appendChild(title).appendChild(author).appendChild(img);
but here simple version, and don't forget to add &callback=handleRespons to the API URL
function handleResponse(obj) {
obj.items.forEach((item, index) => {
if(index > 7) return; // limit 8 result
let div = document.createElement('div');
div.className = 'b-card';
div.innerHTML = `<h1>${item.volumeInfo.title}</h1>
<p><strong>${item.volumeInfo.authors[0]}</strong></p>
<img src="${item.volumeInfo.imageLinks.thumbnail}" alt="${item.singleTitle} by ${item.volumeInfo.authors[0]}" />`
let container = document.querySelector('.booklist-cards');
container.append(div);
})
}
<div class="booklist">
<div class="booklist-cards">
</div>
</div>
<script src="//www.googleapis.com/books/v1/volumes?q=HTML5&callback=handleResponse" async></script>
I am fetching all anchor tag links via web scraping and want to print all links with space between them so while console I used "\n" but it is not making space after end of first link and second link text start without space.
Code:
(async() => {
const html = await axios.get('https://www.xyz');
const $ = await cheerio.load(html.data);
let data = []
$(".div-previews").each((i, elem) => {
console.log('data::', $(elem).find(".header-text a").text() + "\n"); // show links with space between them
})();
})
This should work better - I replaced your each and find
(async() => {
const html = await axios.get('https://www.xyz');
const $ = await cheerio.load(html.data);
console.log('data::',
$(".div-previews .header-text a")
.map(function() { return this.textContent })
.get()
.join("\n") // or .join(" ")
)
})
Example
console.log('data::',
$(".div-previews .header-text a")
.map(function() {
return this.textContent
})
.get()
.join("\n") // or .join(" ")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="div-previews">
<div class="header-text">
Link 1
</div>
</div>
<div class="div-previews">
<div class="header-text">
Link 2
</div>
</div>
<div class="div-previews">
<div class="header-text">
Link 3
Link 4
</div>
</div>
I want to display from json server for example 5 of 100 objects. Is there any parameter like this one which sort?
const url = "http://localhost:8000/players?_sort=points&_order=desc";
const url = "http://localhost:8000/players?_sort=points&_order=desc";
let template = "";
fetch(url)
.then((res) => res.json())
.then((data) => {
data.forEach((player, idx) => {
template += `
<div class='modal-leaderboard__player-name'>
<h2>${idx + 1}. </h2>
<h2 data-player-rank>${player.name} </h2>
<h2 style='margin-left: auto'> <span data-points-rank>${player.points}</span> points</h2>
</div>
`;
});
this.rank.innerHTML += template;
});
if you mean fo example the first 5 items, can add a condition on var idx :
...
if(parseInt(idx)<6){
template+=...
....
this.rank.innerHTML += template;
}
...
I am working with cheerio and I am stuck at a point where I want to get the href value of children div of <div class="card">.
<div class="Card">
<div class="title">
<a target="_blank" href="test">
Php </a>
</div>
<div>some content</div>
<div>some content</div>
<div>some content</div>
</div>
I got first childern correctly but i want to get div class=title childern a href value. I am new to node and i already search for that but i didn't get an appropriate answer.
var jobs = $("div.jobsearch-SerpJobCard",html);
here is my script
const rp = require('request-promise');
const $ = require('cheerio');
const potusParse = require('./potusParser');
const url = "";
rp(url)
.then((html)=>{
const Urls = [];
var jobs = $("div.Card",html);
for (let i = 2; i < jobs.length; i++) {
Urls.push(
$("div.Card > div[class='title'] >a", html)[i].attribs.href
);
}
console.log(Urls);
})
.catch(err => console.log(err));
It looks something like this:
$('.Card').map((i, card) => {
return {
link: $(card).find('a').text(),
href: $(card).find('a').attr('href'),
}
}).get()
Edit: the nlp library is chrono-node and I also recommend timeago.js to go the opposite way