Foreach for array - javascript

I have an array which I populate like so
var list = [];
featureLayer.queryFeatures(querySnTR)
.then((result) => {
result.attachmentInfos.forEach((x) => {
list.push(uriString + "/" + x.id);
});
});
console.log("list", list);
I print out the list with console.log and it returns values inside.
Afterwards I do a foreach to go through all the elements inside and create a div for each of them. The thing is, it doesn't even go in the foreach function.
list.forEach((x) => {
console.log("CL", list);
console.log("x element", x);
var image = document.createElement("img");
image.src = x;
image.className = "queryImg";
document.getElementById("queryResults").appendChild(image);
});
It doesn't print out CL or x element for that matter.
Any ideas as to why?
The whole original code, for reference
startup: function () {
var _that = this;
_this = _that;
this.map.on("click", function (e) {
_this.map.graphics.clear();
identifyTask = new IdentifyTask("https://server/arcgis/rest/services/MUNICIPALITY_BUNDLE/ZK_KATASTAR_NA_ZELENILO/MapServer");
identifyParams = new IdentifyParameters();
identifyParams.tolerance = 10;
identifyParams.returnGeometry = true;
identifyParams.layerIds = [1];
identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_ALL;
identifyParams.width = _this.map.width;
identifyParams.height = _this.map.height;
identifyParams.spatialReference = _this.map.spatialReference;
identifyParams.geometry = e.mapPoint;
identifyParams.mapExtent = _this.map.extent;
identifyTask.execute(identifyParams).then(function (data) {
objId = data[0].feature.attributes.objectid;
const querySnTR = {
where: "1 = 1",
outFields: ["*"]
};
var uriString = "https://server/arcgis/rest/services/MUNICIPALITY_BUNDLE/ZK_KATASTAR_NA_ZELENILO/MapServer/101/" + objId + "/attachments";
var featureLayer = new esri.layers.FeatureLayer(uriString);
featureLayer.queryFeatures(querySnTR)
.then((result) => {
result.attachmentInfos.forEach((x) => {
list.push(uriString + "/" + x.id);
});
});
const myFunction = async () => {
const { attachmentInfos } = await featureLayer.queryFeatures(querySnTR);
const list = attachmentInfos.map(({ id }) => `${uriString}/${id}`);
console.log("list", list);
list.forEach((x) => {
var image = document.createElement("img");
image.src = x;
image.className = "queryImg";
document.getElementById("queryResults").appendChild(image);
});
};
});
});
}

That's a trick on how the console works.
When you are executing the log the list is empty (100% sure) because you are populating it asynchronously. But the console has the reference to it and it will print it afterwards.
That's why your list is empty. You need to handle asynchrony here. You could work with an async/await approach or using promises, that will depend on the rest of your code, this is an example of how to do it with an async function (and rewritted it to modern javascript):
const myFunction = async () => {
const {attachmentInfos} = await featureLayer.queryFeatures(querySnTR);
const list = attachmentInfos.map(({id}) => `${uriString}/${id}`);
console.log("list", list);
list.forEach((x) => {
// put your code here
});
};
Edited:
Now that you share all your code you can simply do:
featureLayer.queryFeatures(querySnTR)
.then((result) => {
result.attachmentInfos.forEach((attachmentInfo) => {
var x = uriString + "/" + attachmentInfo.id
var image = document.createElement("img");
image.src = x;
image.className = "queryImg";
document.getElementById("queryResults").appendChild(image);
});
});
I would recommend you also to give vars meaningful names, not x but attachmentInfo, etc...

Related

Node JS function that return https get request final edited data

Hello everybody I have a problem with the Node JS function that I want it to return https get request final edited data, I know there are a lot of solutions for this async problem but I tried them all and still can't figure out what is wrong with my code?
here is my function without any other solutions editing:
function getMovie(apiKey, gen) {
const baseUrl = "https://api.themoviedb.org/3/discover/movie?api_key=" + apiKey + "&language=en-US&include_adult=false&include_video=false&page=1&with_genres=" + gen;
https.get(baseUrl, function (responce) {
console.log(responce.statusCode);
var d = "";
responce.on("data", function (data) {
d += data;
});
responce.on("end", () => {
const finalData = [];
const moviesData = JSON.parse(d);
const result = moviesData.results;
const maxx = result.length;
const rand = Math.floor(Math.random() * maxx);
const title = result[rand].title;
const rDate = result[rand].release_date;
const overview = result[rand].overview;
const imageRoot = result[rand].poster_path;
const movieId = result[rand].id;
const movieRating = result[rand].vote_average;
// here will push those variables to finalData array
// then return it
return finalData;
});
}).on('error', (e) => {
console.error(e);
});
}
and want after this finalData returns:
const finalResult = getMovie(apiKey, genre);
it always returns undefined, How can I fix this? please anyone ca help me with this problem
thanks in advance.
I solved this problem using promises using this code:
const rp = require('request-promise');
function getMovie(url) {
// returns a promise
return rp(url).then(body => {
// make the count be the resolved value of the promise
let responseJSON = JSON.parse(body);
return responseJSON.results.count;
});
}
getMovie(someURL).then(result => {
// use the result in here
console.log(`Got result = ${result}`);
}).catch(err => {
console.log('Got error from getMovie ', err);
});

cant pass data from textbox inside a loop

so im getting my data from Darksky api, i have elements generated with loops, and i update the text content of those via loop of the api data array. whenever i search, everthing else static changes values, not the one inside the loop
function search(ele) {
if(event.key === 'Enter') {
var url3 = 'https://geocode.xyz/' + ele.value +'?json=1' //this is where i convert the long,lat to city name
fetch(url3)
.then(z => z.json())
.then(z => {
locres = (z.latt+','+z.longt)
render()
renderLoop()
})
}
}
function renderLoop(){
var proxyUrl = 'https://cors-anywhere.herokuapp.com/';
var url1 = 'https://api.darksky.net/forecast/c34e122a56ae30a3090687878bce72c3/' + locres + '?units=auto' //i have to use proxy because of CORS
fetch(proxyUrl + url1)
.then(x => x.json())
.then(x => {
var skycons = new Skycons({"color": "white"});
skycons.set("icon0", Skycons = x.currently.icon);
skycons.play();
console.log(x.daily.data)
for(i=0;i<8;i++){
console.log(x.daily.data[i].time)
console.log(x.daily.data[i].summary)
const divs = document.createElement('div')
divs.className = ('week-day-container')
const divsholdr = document.querySelector('.week-stage')
const canv = document.createElement('canvas')
canv.id = ('icons'+(i+1))
canv.height = 100
canv.width = 70
divs.appendChild(canv)
divsholdr.appendChild(divs)
const dates = document.createElement('p')
dates.textContent = x.daily.data[i].time
divs.appendChild(dates)
const temp = document.createElement('p')
temp.textContent = 'High: '+ x.daily.data[i].temperatureHigh + 'Low: ' + x.daily.data[i].temperatureLow
divs.appendChild(temp)
const summ = document.createElement('p')
summ.textContent = x.daily.data[i].summary
divs.appendChild(summ)
}
for(y=0;y<8;y++){
skycons.set('icons'+(y+1), Skycons = x.daily.data[y].icon)
}
})
}

Asynchronous test function

I'm trying to create a function to testing asynchronous code, but I'm kind of lost, I want the TEST_F and TEST function below also work with asynchronous code, such as loading the image for example.
const CHECK = (actual, expected) => {
return (actual === expected);
};
const TEST = (name, ...testFunctions) => {
console.log(name+':');
for (let test of testFunctions)
console.log(test);
};
const TEST_F = (name, f) => {
const tStart = performance.now();
const check = f();
const tEnd = performance.now();
const duration = tEnd - tStart;
const details = name + ': ' + '(' + duration + ') = ' + check;
return details;
};
const imageDownload = (path, successCallback) => {
let img = new Image();
img.addEventListener("load", successCallback, false);
img.src = path;
return img;
};
TEST("TestImage",
TEST_F("testImageDownload", () => {
let spyCountSuccess = 0;
const expectedCountSuccess = spyCountSuccess + 1;
const successCallback = () => {
spyCountSuccess++;
};
const pathImage = 'https://i.imgur.com/Wutekcp.jpg';
imageDownload(pathImage, successCallback);
const actualCountSuccess = spyCountSuccess;
return CHECK(actualCountSuccess, expectedCountSuccess);
})
);
With the code above I will always i get false, even if the image is loaded, because I am not dealing right with the concept of asynchronous, I would like to understand how to adapt the code thus to also test ascincrono code.
I was able to test the asynchronous code after some tests. I do not know if I'll keep it that way, but it's working, I'll try to study these lines and see what I can improve:
const CHECK = (actual, expected) => {
return (actual === expected);
};
const TEST = (name, ...testFunctions) => {
console.log(name+':');
for (let test of testFunctions)
if(test === undefined)
continue;
else
console.log(test);
};
const TEST_F = (name, f) => {
const tStart = performance.now();
const check = f();
const tEnd = performance.now();
const duration = tEnd - tStart;
const details = name + ': ' + '(' + duration + ') = ' + check;
return details;
};
const TEST_F_ASYNC = (name, f) => {
const tStart = performance.now();
f((check) => {
const tEnd = performance.now();
const duration = tEnd - tStart;
const details = name + ': ' + '(' + duration + ') = ' + check;
console.log(details);
});
};
const imageDownload = (path, successCallback) => {
let img = new Image();
img.addEventListener("load", successCallback, false);
img.src = path;
return img;
};
TEST("TestImage",
TEST_F_ASYNC("testAsync", (done) => {
let spyCountSuccess = 0;
const expectedCountSuccess = spyCountSuccess + 1;
const successCallback = () => {
spyCountSuccess++;
const actualCountSuccess = spyCountSuccess;
const result = CHECK(actualCountSuccess, expectedCountSuccess)
done(result);
};
const pathImage = 'https://i.imgur.com/Wutekcp.jpg';
imageDownload(pathImage, successCallback);
}),
TEST_F('testSync', () => {
return CHECK(1, 1);
})
);

How to wait for forEach to complete when each iteration calls an asynchronous options?

Alright, here's what the plan is. Go through each file, add the file into the array. Once all files are added, then combine them using the JSZipUtility and Docxtemplater:
'click .merge-icon': (e) => {
var programId = Router.current().url.split('/').pop();
var programObj = Programs.findOne(programId);
var insertedDocuments = [];
var i = 0;
var count = programObj.activityIds.count;
var fileDownloadPromise = new Promise((resolve, reject) => {
programObj.activityIds.forEach(function(activityId) {
var activityObj = Activities.findOne(activityId);
var documentObj = ActivityFiles.findOne(activityObj.documents.pop()._id);
JSZipUtils.getBinaryContent(documentObj.url(), callback);
function callback(error, content) {
var zip = new JSZip(content);
var doc = new Docxtemplater().loadZip(zip);
var xml = zip.files[doc.fileTypeConfig.textPath].asText();
xml = xml.substring(xml.indexOf("<w:body>") + 8);
xml = xml.substring(0, xml.indexOf("</w:body>"));
xml = xml.substring(0, xml.indexOf("<w:sectPr"));
insertedDocuments.push(xml);
i++;
if (i == count - 1) {
resolve();
}
}
});
});
fileDownloadPromise.then(() => {
JSZipUtils.getBinaryContent('/assets/template.docx', callback);
function callback(error, content) {
console.log(content);
var zip = new JSZip(content);
var doc = new Docxtemplater().loadZip(zip);
setData(doc);
}
function setData(doc) {
doc.setData({
body: insertedDocuments.join('<w:br/><w:br/>')
});
doc.render();
useResult(doc);
}
function useResult(doc) {
var out = doc.getZip().generate({
type: 'blob',
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
});
saveAs(out, programObj.name + '.docx');
}
});
}
Turns out nothing's happening. What's wrong with the execution of this Promise here ?
I'm only calling resolve when every file has been loaded in the array.

Can't get list filled from a promise and use it in html - aurelia

I can't get the finalList filled to use in my html file, it wil run the code to fill it before the promise all code. I need to use this array in my html document so it has to be a this.variable I am using Aurelia.
activate() {
var repoList = [];
var repos = this.http.fetch({Link to github api})
.then(response => response.json())
.then(repos => this.repos = repos);
var trello = new Trello;
trello.getBoards().then(boardList => this.boards = boardList);
var boards = trello.getBoards();
//add github repo to the associated trello board (works)
Promise.all([boards, repos]).then(function(values) {
var count = 0;
for (var i in values[0]) {
for (var a in values[1]) {
if (values[1][a].hasOwnProperty("name")) {
var repo = values[1][a].name.toLowerCase();
var board = values[0][i]['name'].toLowerCase();
repoList[count] = repo;
count++;
if (repo == board) {
console.log(repo + " " + board)
}
}
}
}
});
//this list is always empty (The problem)
this.finalList = repoList;
this.title = "Trello Boards";
}
Something like this should do it. Hard to decipher what's going on in the for loops.
activate() {
let reposPromise = this.http.fetch({Link to github api})
.then(response => response.json());
let boardsPromise = new Trello().getBoards();
return Promise.all([boardsPromise, reposPromise])
.then(([boards, repos]) => {
this.boards = boards;
this.repos = repos;
this.finalList = [];
for (var i in boards) {
for (var a in repos) {
if (values[1][a].hasOwnProperty("name")) {
var repo = values[1][a].name.toLowerCase();
var board = values[0][i]['name'].toLowerCase();
this.finalList.push(repo);
if (repo == board)
{
console.log(repo + " " + board)
}
}
}
}
});
this.title = "Trello Boards";
}
I believe Your finalList should be set inside the promise handler. Like this.
activate() {
var repoList = [];
//I always use this, and I am not sure what do you mean
//by this.finalList, but still I assume you know what you are doing
//And hence I use this!
var that = this;
var repos = this.http.fetch({Link to github api})
.then(response => response.json())
.then(repos => this.repos = repos);
var trello = new Trello;
trello.getBoards().then(boardList => this.boards = boardList);
var boards = trello.getBoards();
//add github repo to the associated trello board (works)
Promise.all([boards, repos]).then(function(values) {
var count = 0;
for (var i in values[0]) {
for (var a in values[1]) {
if (values[1][a].hasOwnProperty("name"))
{
var repo = values[1][a].name.toLowerCase();
var board = values[0][i]['name'].toLowerCase();
repoList[count] = repo;
count++;
if (repo == board)
{
console.log(repo + " " + board)
};
}
};
};
//I believe when promise resolves. You should set the repoList.
that.finalList = repoList;
that.title = "Trello Boards";
});
}
My question is, do you really wanna set title and finalList to this? Just asking.
Hope this helps!

Categories

Resources