Getting empty array - javascript

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()

Related

Adding multiple li's to ul in 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

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()

for of loop return same item multiple times api double fetch

Console and browser display this In the first for of loop I get 10 different results as expected. in the second for loop when i call it it gives me 10 times the same result.
why this happens and how do i fix it?
const inputValue = document.getElementById("searchbarInput").value;
const searchUrl = `https://stock-exchange-dot-full-stack-course-services.ew.r.appspot.com/api/v3/search?query=${inputValue}&limit=10&exchange=NASDAQ`;
const options = {
filter: '',
sort: 1}
async function displaydata() {
let url = searchUrl;
let response = await fetch(url);
let data = await response.json();
//log company info
const mappedList = data.map((x) => ({
name: x.name,
symbol: x.symbol,
ceo: x.ceo
}))
for (let info of mappedList) {
const companyInfo = await fetchMoreInfo(info.symbol);
ceo = companyInfo.profile.ceo; // here returns a 10 different items
}
document.getElementById('root').replaceChildren();
for (comp of mappedList) {
const div = document.createElement('div');
div.innerHTML = `${ceo} ${comp.name}(${comp.symbol})` + "<br>";
document.getElementById('root').appendChild(div); //here it gives me the same 10 itmes}}
const fetchMoreInfo = async(companySymbol) => {
let url = `https://stock-exchange-dot-full-stack-course-services.ew.r.appspot.com/api/v3/company/profile/${companySymbol}`;
let response = await fetch(url);
let compData = await response.json();
return compData;
}

Still getting a double click error even though the flow is right

let fieldName = ""
let jsonResponse = ""
let collectionName = ""
let fieldEl = document.getElementById("field_el")
let inputEl = document.getElementById("input-el")
let buttonEl = document.getElementById("button-el")
let collectionData = {
averagePrice: ""
}
const getStatsAvgPrice = {
currentAP: function() {
collectionData.averagePrice = jsonResponse.stats["average_price"]
}
}
function callApi(collectionName,fieldName) {
fetch(`https://api.opensea.io/api/v1/collection/${collectionName}/${fieldName}`)
.then(response => response.json())
.then(response => jsonResponse = response)
.then(getStatsAvgPrice.currentAP())
.then(render())
.catch(err => console.error(err));
}
function render() {
document.getElementById("report").innerHTML = JSON.stringify(collectionData.averagePrice);
console.log(JSON.stringify(collectionData.averagePrice))
}
buttonEl.addEventListener("click", () => {
collectionName = inputEl.value
fieldName = fieldEl.value
callApi(collectionName,fieldName)
})
How can I get this to work? Perhaps make more functions? Add to the dom? Any ideas would be helpful. Still getting a double click error even though the flow is right.

How to output TreeModel Js model as JSON

So I'm triyng to update some ids from a categories tree using TreeModelJS.
after editing I would like to dump the tree to a file in JSON format.
but when outputing other keys from TreeModel gets outputed as well.
How could I output edited tree as JSON (model only)?
I managed to replace other keys values with null and so far I got this:
const axios = require('axios')
const TreeModel = require('tree-model')
const fs = require('fs')
const url = 'https://my-api-uri-for-categories'
const dumpPath = `${process.cwd()}/data/test/categories.json`
const getCategories = async () => {
try {
const response = await axios.get(url)
return response.data.categories
} catch (error) {
console.log('Error reading categories', error)
}
}
const dumpJsonTofile = data => {
try {
console.log('Dumping to file')
console.log(data)
fs.writeFileSync(
dumpPath,
JSON.stringify(data, (k, v) => {
if (k === 'parent' || k === 'config' || k === 'children') return null
else return v
}),
'utf8'
) // write it back
} catch (error) {
console.log('Error dumping categories', error)
}
}
const scraping = async category => {
try {
const response = await axios.get(category.url)
const document = response.data
const json = document.match(/{"searchTerm"(.*);/g)[0]
const data = JSON.parse(json.replace(';', ''))
return data
} catch (error) {
console.log(`Error while scraping category: ${category.name}`, error)
}
}
async function run() {
const categories = await getCategories()
const categoriesTree = new TreeModel({
childrenPropertyName: 'items',
})
const root = categoriesTree.parse({ id: 0, origin: {}, items: categories })
root.walk(async node => {
const category = node.model
console.log(`scraping category: ${category.name}...`)
if (!category.url) return console.log(`skipping (root?)...`)
const data = await scraping(category)
category.id = data.categoryId
})
dumpJsonTofile(root)
}
run()
but that still outputs a Node object like this:
{
"config":null,
"model":{},
"children":null
}
I need to output all the tree showing only the model key value for each item
Try JSON.stringify(root.model).

Categories