Unable to appendChild data from a promise in javascript - javascript

I'm having problems when appending to the body the data returned by a promise. I console log it and everything seem to be working fine, however, when I try to do a simple appendChild to the body, I receive an error which says: "functions.js:73 Uncaught (in promise) TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'"
I looked this error up on the internet, here in StackOverflow and someone has already asked the same question, but the answer he got doesn't work for me.
Please, can you take a look and help me figure out what's wrong here?
Thanks.
fetchUsers()
.then(data => data.json())
.then(json => {
listUsers(json);
return fetchJanet();
})
.then(janetData => janetData.json())
.then(janet => listJanet(janet.data));
function fetchUsers() {
return fetch("https://reqres.in/api/users");
}
function listUsers(json) {
users = json.data;
users.forEach((element, i) => {
n = document.createElement("h3");
n.innerHTML =
element.first_name + " " + element.last_name + " have an index of: " + i;
document.body.appendChild(n);
document.getElementById("loading").style.display = "none";
});
}
function fetchJanet() {
return fetch("https://reqres.in/api/users/2");
}
function listJanet(element) {
console.log(element);
name = document.createElement("p");
name.innerHTML = element.first_name + " " + element.last_name;
document.body.appendChild(name);
}

Related

how find which element cause error in promis.map and log it in console, or skip it by code?

I using following code, but some URL from URL List, get 500 Error because of structure of the page.
I get the error exactly on .map((htmlOnePage, index) => line when some URLs page not valid, and the flow control of program goes at Catch Part. How I can find which URL is invalid?
const requestPromise = require('request-promise');
const Promise = require('bluebird');
const cheerio = require('cheerio');
for (var i = 1; i <= 250; i++) {
p = "https://mywebsite.com/" + i.toString()
urls[i - 1] = p
}
Promise.map(urls, requestPromise)
.map((htmlOnePage, index) => {
const $ = cheerio.load(htmlOnePage);
$('.txtSearch1').each(function() {
var h = "";
h = $(this).text()
h = h.replace(/(\r\n|\n|\r)/gm, "")
html44.push(h)
})
shareTuple[urls[index]] = html44;
html44 = []
fs.writeFileSync("data.json", JSON.stringify(shareTuple))
}, {
concurrency: 1
})
.then()
.catch((e) => console.log('We encountered an error' + e));
in other word how I can show which URL get into catch?
You should add try catch phrases inside all iterating functions to pin point the problem. and do the logging for every one based on op that they are catching.
For example i would wrap it like this:
try {
const $ = cheerio.load(htmlOnePage);
$('.txtSearch1').each(function () {
try {
var h="";
h=$(this).text()
h= h.replace(/(\r\n|\n|\r)/gm, "")
html44.push (h)
}catch (error) {
console.log('Error in getting p text');
console.log(error);
}
} catch (error) {
console.log('Error in loading'+ htmlOnePage);
console.log(error);
}
You can break down the error more by looking up through error object values to find the problem if you want to manualy remove it.
The other way to programaticaly remove it is to try doing the request for the page after creating it and also wrapping it in try catch. If it throws an exception you can add in catch to remove it from the list.
That text before console log of error is just so you can see where it broke.
Use a wrapper around requestPromise that catches the error. Note, the return undefined is not really needed. It's just for clarification, that in case of an error nothing is returned.
const requestPromise = require('request-promise');
....
const noThrowRequest = async (url) => {
try {
return await requestPromise(url);
} catch (e) {
return undefined;
}
}
Or if you prefer .then().catch() you can do it as follows
const noThrowRequest = (url) => {
return requestPromise(url)
.then(result => { return result; })
.catch(e => { return undefined; });
}
And then use that wrapper instead of requestPromise and check whether the current result valid or not. I don't know what you want to do in case of an invalid result, so I just return from the callback without any further ado. Adapt that if necessary.
Promise.map(urls, noThrowRequest)
.map((htmlOnePage, index) => {
if (htmlOnePage === undefined) {
console.log(`there was an error at index ${index}`);
return; //stop callback for erronous indexes.
}
...
}

Why am I getting Uncaught TypeError: sendToServer(...) is not a function in firebase

I am making a messaging system using firebase. It properly sends messages to firebase, however when I send messages, it keeps throwing the error:
Uncaught TypeError: sendToServer(...) is not a function
at sendToP.js:21
at EventRegistration.ts:109
at Qe (util.ts:539)
at EventQueue.ts:159
at Pi (EventQueue.ts:127)
at Ii (EventQueue.ts:107)
at wo (Repo.ts:365)
at ro.s.server_ [as onDataUpdate_] (Repo.ts:230)
at ro.onDataPush_ (PersistentConnection.ts:661)
at ro.onDataMessage_ (PersistentConnection.ts:654)
Here is the function that adds the message to the database
function cleanMessage(message){
message = message.split(" ").map(x => badWords.indexOf(x) != -1? x = (x.split("").map(c => c = '*')).join(""): x = x).join(" ")
return message
}
function sendToServer(obj) {
autoId = firebase.database().ref('users').push().key
firebase.database().ref('/general/' + autoId.toString()).set(obj)
}
$(".send").click(function() {
firebase.database().ref('Users/' + firebase.auth().currentUser.uid).on('value', function(snapshot) {
digits = snapshot.val().digits
let message = cleanMessage($(".enter-message").val())
let messageObject = {
message: message,
sender: digits
}
sendToServer(messageObject)
$(".enter-message").val('')
});
})
Here is the function that gets the last message. Note: This is on a separate script
// Add message to the browser window
firebase.database().ref('general').orderByKey().limitToLast(1).on("value", function(snapshot){
message = ""
snapshot.forEach(function(elem){
message = elem.val().message
})
})
I greatly appreciate any help.

How do i push a variable after using split function in javascript?

error: Uncaught (in promise) TypeError: Cannot read property
'push' of undefined error line: " this.name[i].push(arrayData[0]);
"
I do not understand since the line before console.log("data is loaded:" + arrayData[0]); is working!
Is it something about async? Can someone please help me out?
Here is my code:
data: {
name: []
},
methods: {
LoadData: function() {
console.log("onload fundtion. \n");
fetch('http://localhost/store/skininfor.txt')
.then(response => response.text())
.then((data) => {
// console.log(data);
var textByLine = data.split("\n");
for (var i = 0; i < textByLine.length; i++) {
var arrayData = textByLine[i].split(",");
console.log("data is loaded:" + arrayData[0]);
if (arrayData[0] !== undefined) {
this.name[i].push(arrayData[0]);
}
}
});
},
By this way this.name[i].push(arrayData[0]); you are trying to push an element into another element this is why you have that error.
this.name is the tab and this.name[i] is one element so it should be this.name.push(arrayData[0]);
you don't have any element in the name array therefore you should push like this.
this.name.push(arrayData[0]);
You probably need to assign instead of pushing, i.e.
this.name[i] = arrayData[0];
(Although I can't be sure. If you defined example input data and desired output, that would be helpful).

Consuming APIs - How to connect to an API

I have most of my code written but I'm not sure what I'm doing wrong on this:
let url = 'https://cors-anywhere.herokuapp.com/https://newsapi.org/v2/top-headlines?sources=hacker-news&apiKey=3dcfcd098261443dae7c7d002f25c062';
fetch(url)
.then(r =>{
return r.json();
})
.then(data => {
let articles = data.articles;
let storyList = document.createElement("ul");
let body = document.querySelector("body");
body.appendChild(storyList);
})
articles.map(articles => {
let storyItem = document.createElement("li");
storyItem.innerHTML = 'a href = "' + articles.href + '">' + articles.title + "</a>";
storyList.appendChild(storyItem);
})
.catch(e => {
console.log('An error has occurred: ${e}');
});
I had taken out the < > from the API code and tried switching things around like switching some properties to say something different but could someone help me understand this a bit better? Thanks in advance!
There were several things that you were doing wrong.
No need to use a proxy when the API you are consuming allows cors requests.
You were trying to access the "articles" out of scope and before the promise was resolved
You were using the wrong method, IMO, on the "articles" array. From here: Array.prototype.map()
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
but you were not trying create a new array, you just wanted to iterate the array's elements. That is what Array.prototype.forEach() is for.
You used single quotes ' on your template literal instead of back-ticks `
let url = 'https://newsapi.org/v2/top-headlines?sources=hacker-news&apiKey=3dcfcd098261443dae7c7d002f25c062';
fetch(url)
.then(response => {
return response.json();
})
.then(data => {
let list = document.createElement('ul');
document.querySelector("body").appendChild(list);
data.articles.forEach(article => {
let item = document.createElement('li');
item.innerHTML = '' + article.title + "";
list.appendChild(item);
});
})
.catch(e => {
console.log(`An error has occurred: ${e}`);
});

Firebase Uncaught TypeError: Cannot read property 'forEach' of undefined

I'm trying to count the number of misbehavior on the two routes I've made in my database. Below are the structure of my firebase database under drivers and reports database respectively:
[drivers database] - i.stack.imgur.com/Q6GKs.png
[reports database] - i.stack.imgur.com/ALWPu.png
Here's my counter for counting the number of misbehavior:
<script>
var route1Count = 0;
var route2Count = 0;
var drivers;
var reports;
var driversRef = firebase.database().ref('drivers/');
var reportsRef = firebase.database().ref('reports/');
driversRef.once('value', (snapshot) => {
drivers = snapshot;
});
reportsRef.once('value', (snapshot) => {
reports = snapshot;
});
drivers.forEach((driver) => {
var violationCount = reports.filter((report) => report.val().plateNumber === driver.key).length;
if(driver.val().route === "Fairview - Quiapo"){
route1Count += violationCount;
}else if(driver.val().route === "Quiapo - Fairview"){
route2Count += violationCount;
}
});
document.getElementById("demo").innerHTML = "route1: " + route1Count + "route2: " + route2Count;
</script>
I get this error message:
Uncaught TypeError: Cannot read property 'forEach' of undefined
at drivers.forEach, all inputs will be greatly appreciated! Thanks!
Error Message :
you could nest them, or if you run this in an environment that supports es6's Promise object (which your code suggests), you could use the once() returning a promise and more elegantly do:
Promise.all([driversRef.once('value'), reportsRef.once('value')])
.then(([driversSnapshot, reportsSnapshot]) => {
// ...
})

Categories