Adding multiple li's to ul in JavaScript - javascript

const getSearch = async function () {
try {
const res = await fetch(
`http://dataservice.accuweather.com/locations/v1/cities/search?apikey=${apiKey}&q=${inputValue}`
);
const data = await res.json();
// console.log(data);
const dataArr = Object.entries(data);
dataArr.forEach(([key, value]) => {
const city = value.AdministrativeArea.LocalizedName;
const country = value.Country.LocalizedName;
const countryCode = value.Country.ID;
const markup = `
<li class="search-result search-result--${key}">${city}, ${country}, ${countryCode}</li>
`;
console.log(markup);
});
ul.innerHTML = '';
ul.insertAdjacentHTML('afterbegin', markup);
} catch (err) {
console.error(err);
}
};
I am trying to add all li's to my ul. When I console.log(markup), the results come back separately, but when I insertAdjacentHTML() only the last li is displayed.
This is for search results, so the amount of li's is unknown for each search input, and I want the li's to match the number of results.

I'm surprised that it even worked once:
const getSearch = async function () {
try {
const res = await fetch(
`http://dataservice.accuweather.com/locations/v1/cities/search?apikey=${apiKey}&q=${inputValue}`
);
const data = await res.json();
// console.log(data);
const dataArr = Object.entries(data);
dataArr.forEach(([key, value]) => {
const city = value.AdministrativeArea.LocalizedName;
const country = value.Country.LocalizedName;
const countryCode = value.Country.ID;
const markup = `
<li class="search-result search-result--${key}">${city}, ${country}, ${countryCode}</li>
`;
console.log(markup);
// try this
ul.insertAdjacentHTML('afterbegin', markup);
});
} catch (err) {
console.error(err);
}
};
I would rather use createElement than innerHTML

Related

Getting empty array

I have declared three arrays dronesList, ndzDrones, pilotsList. After all the conditions are executed, I am getting updated data of dronesList and ndzDrones but the pilotsList is empty, although I'm receiving the data and pilotsList is updated inside the condition after pushing but outside of condition getting Empty[] of pilotsList. Can't figure what I'm missing here.
Any help will be appriciated
let dronesList = []
let ndzDrones = []
try {
const xml = await fetch(
"https://assignments.reaktor.com/birdnest/drones"
).then((res) => res.text())
.catch((error) => {
console.error('Error:', error)
})
const jsonData = parser.parse(xml)
const dronesData = jsonData.report.capture.drone;
dronesList = dronesData;
if(dronesList !== ""){
dronesList.map((drone) =>{
const x = Number(drone.positionX)
const y = Number(drone.positionY)
if(checkVoilation(x, y)){
ndzDrones = ndzDrones.concat(drone)
}
})
}
let pilotsList = []
if(ndzDrones !== ""){
ndzDrones.forEach(async (drone) => {
const serial = drone.serialNumber
const response = await fetch(`https://assignments.reaktor.com/birdnest/pilots/${serial}`)
const data = await response.json()
pilotsList = pilotsList.concat(data)
})
}
console.log(dronesList) //Output [drones]
console.log(ndzDrones) //Output [ndzDrones]
console.log(pilotsList) //Output [] Empty Array
res.status(200).json(pilotsList)
} catch (error) {
res.status(404).json({message: error.message})
}
const pilotsList = await Promise.all(ndzDrones.map(async (drone) => {
const serial = drone.serialNumber
const response = await fetch(`https://assignments.reaktor.com/birdnest/pilots/${serial}`)
const data = await response.json()
return data
})).flat()

JS WebDriverIO how to check if tag h1 is present on a page

I tried doing like this:
await browser.url(https://webdriver.io/');
expect(browser).toHaveText('h1')
so tried:
await browser.url(https://webdriver.io/');
await browser.findElement('xpath', 'h1')
But it doesn't help
Can someone tell me how to check for the presence of the h1 tag in the loop? The test immediately crashes and does not print pages that do not have h1
const url = 'https://webdriver.io/';
const crossFetch = require('cross-fetch');
const links = [];
describe('test', async () => {
beforeEach(async function () {
const result = await crossFetch(`${url}/wp-json/wp/v2/pages/?per_page=100`);
const pages = await result.json();
pages.forEach(page => links.push(page.link));
});
it('Check Headers', async () => {
const array1 = [];
const array2 = [];
for (const elem of links) {
await browser.url(elem);
elem.click;
const classNameAndText = await $('<h1>')
console.log('HAS h1 - ' + await classNameAndText.getText()) // outputs: h1
if (classNameAndText) {
array1.push(elem);
} else {
array2.push(elem);
}
}
if (array2.length > 0) {
array2.forEach(function (elem1) {
console.log('NOT h1 - ' + elem1);
})
}
})
});
this is how i solved the issue:
const url = 'https://webdriver.io/';
const crossFetch = require('cross-fetch');
const links = [];
describe('test', async () => {
beforeEach(async function () {
const result = await crossFetch(`${url}/wp-json/wp/v2/pages/?per_page=100`);
const pages = await result.json();
pages.forEach(page => links.push(page.link));
});
it('Check Headers', async () => {
const errorsUrls = [];
for (const url of links) {
await browser.url(url);
const classNameAndText = await $('h3');
if (typeof classNameAndText.error !== 'undefined') {
errorsUrls.push(url);
}
}
if (errorsUrls.length > 0) {
throw new Error( `
Header Not Found:
${errorsUrls.join('\r\n')}
`);
}
})
});

innerText value is undefined when returned from promise despite being there on the console

I'm using Node JS, here's the code
import fetch from 'node-fetch';
import { JSDOM } from 'jsdom';
import {Appartment} from "./models/Appartment.mjs"
let applist = []
let multipleDivs = []
async function kijAppartments() {
try {
const kijCall = await fetch(`https://www.kijiji.ca/b-ville-de-montreal/appartement-4-1-2/k0l1700281?rb=true&dc=true`);
if(!kijCall.ok) {
throw new Error (
`HTTP error: ${kijCall.status}`
)
}
const response = await kijCall.text()
const dom = new JSDOM(response)
multipleDivs = dom.window.document.querySelectorAll(".info-container")
// console.log(multipleDivs)
return multipleDivs
}
catch(error) {
console.log("Error Made")
console.log(error)
}
}
async function arrayOfApps() {
await kijAppartments()
.then(data => {
data.forEach(div => {
const newApp = new Appartment
newApp.price = div.childNodes[1].innerText
newApp.title = div.childNodes[3].innerText
newApp.description = div.childNodes[7].innerText
console.log(newApp)
})
})
}
await arrayOfApps()
If you go on this link and try the following const aList = document.querySelectorAll(".info-container"), you get access to all of the nodes, innerHTML and innerText all work and give you access to the actual value but for some reason, when I try to run this code in the terminal, the value of all my objects is undefined.
You should use textContent instead of innerText.
Here's my solution:
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
const jsdom = require('jsdom');
const { JSDOM } = jsdom;
class Appartment {
price
title
description
location
}
let multipleDivs = []
const appartments = []
function trim(text){
return text.replace(/(\r\n|\n|\r)/gm, "").trim()
}
async function fetchKijijiAppartments() {
const url = `https://www.kijiji.ca/b-ville-de-montreal/appartement-4-1-2/k0l1700281?rb=true&dc=true`
try {
const kijijiRes = await fetch(url);
if (!kijijiRes.ok) {
throw new Error(
`HTTP error: ${kijijiRes.status}`
)
}
const response = await kijijiRes.text()
// console.log("DB: ", response)
const dom = new JSDOM(response)
multipleDivs = dom.window.document.querySelectorAll(".info-container")
//console.log("DB: " multipleDivs)
return multipleDivs
} catch (error) {
console.log("Error Made")
console.log(error)
}
}
async function scrapeAppartments() {
await fetchKijijiAppartments()
.then(data => {
data.forEach(div => {
const appartement = new Appartment
appartement.price = trim(div.querySelector(".price").textContent)
appartement.title = trim(div.querySelector(".title").textContent)
appartement.description = trim(div.querySelector(".description").textContent)
console.log("DB: ", appartement)
appartments.push(appartement)
})
})
}
scrapeAppartments()

Display items after fetching API after chosing Option from Selct menu

My HTML:
<body>
<form name="slectMovie">
IMDb rating:
<button type="submit" value="Select">Select</button>
</form>
<script src="script.js"></script>
</body>
My JS:
const getData = async () => {
try {
const res = await fetch("http://134.209.87.8:1337/api/movies");
const data = await res.json();
console.log(data);
const imdbSelect = document.createElement("select");
document.querySelector("form").append(imdbSelect);
if (data.data.length > 0) {
const IMDbRating = [
...new Set(data.data.map((x) => x.attributes.IMDbRating)),
];
IMDbRating.forEach((category) => {
const option = document.createElement("option");
option.textContent = category;
imdbSelect.append(option);
});
}
} catch (err) {
console.log(err);
}
};
getData();
I have one selection, that is movie rating, that I'm fetching from created API, and adding option values from API.
I would like to know how do I display items underneath form that are only selected in select tag.
For example if I chose first option, I would like to display items underneath form that only match that criteria, if I chose other option to display only itmes that have that option criteria.
there are many ways to achieve this. below is one of these.
In The html, add new line to display the items.
<form name="slectMovie">
IMDb rating:
<button type="submit" value="Select">Select</button>
</form>
<ul id="theList"></ul>
<script src="script.js"></script>
in javascript add few lines for display functionality
let data = [];
function dispplayData({ target }) {
const selectedItem = data.data.filter(
(d) => d.attributes.IMDbRating === Number(target.value)
);
const displayList = document.querySelector("#theList");
displayList.innerHTML = "";
selectedItem.forEach((item) => {
let listItem = document.createElement("li");
listItem.textContent = item.attributes.title;
displayList.appendChild(listItem);
});
console.log(selectedItem);
}
const getData = async () => {
try {
const res = await fetch("http://134.209.87.8:1337/api/movies");
data = await res.json();
console.log(data);
const imdbSelect = document.createElement("select");
document.querySelector("form").append(imdbSelect);
imdbSelect.addEventListener("change", dispplayData);
if (data.data.length > 0) {
const IMDbRating = [
...new Set(data.data.map((x) => x.attributes.IMDbRating)),
];
IMDbRating.forEach((category) => {
const option = document.createElement("option");
option.textContent = category;
imdbSelect.append(option);
});
}
} catch (err) {
console.log(err);
}
};
getData();
Hope this helps you.

How can I get error message of weatherapi using fetch

I'm unable to get an error response for the web app, it displays if there's a valid response but doesn't display anything on a bad request. How can I get the error message either on the console or as json string
Here's the code below
const getWeather = () => {
let city = document.querySelector("input").value;
fetch(
`http://api.weatherapi.com/v1/current.json?key=ca7ec552bc034514a9792135211812&q=${city}&aqi=no`
)
.then((data) => data.json())
.then((data) => displayWeather(data));
};
document.querySelector("button").addEventListener("click", () => {
getWeather();
document.querySelector("input").innerText = "";
});
const displayWeather = (data) => {
const localInfo = data.location.localtime;
const name = data.location.name;
const icon = data.current.condition.icon;
const text = data.current.condition.text;
const temp = data.current.temp_c;
const humidity = data.current.humidity;
const country = data.location.country;
const windSpeed = data.current.wind_kph;
const code = data.current.condition.code;
const error =data.error.message;
console.log(name, icon, text, temp, humidity, country, windSpeed, code, error);
Live code at this time of writing this: https://github.com/samuelajala01/my-weather-app/blob/master/script.js
The weather API will only send error sub object if there is error, otherwise it will just send current and location sub objects, hence you just had to add a check for existence of error object in response data
Something like this :
document.querySelector("button").addEventListener("click", () => {
getWeather();
document.querySelector("input").innerHTML = " ";
});
const displayWeather = (data) => {
if (data.error) {
alert(data.error.message);
} else {
const localInfo = data.location.localtime;
const name = data.location.name;
const icon = data.current.condition.icon;
const text = data.current.condition.text;
const temp = data.current.temp_c;
const humidity = data.current.humidity;
const country = data.location.country;
const windSpeed = data.current.wind_kph;
const code = data.current.condition.code;
console.log(name, icon, text, temp, humidity, country, windSpeed, code);
}
}
const getWeather = () => {
let city = document.querySelector("input").value;
fetch(
`http://api.weatherapi.com/v1/current.json?key=ca7ec552bc034514a9792135211812&q=${city}&aqi=no`
)
.then((data) => data.json())
.then((data) => displayWeather(data))
};

Categories