undefined is not an object (evaluating 'this.http.get') - node.js

Can somebody PLEASE tell me what I'm doing wrong here :
I'm sorry, I feel like I'm losing my mind for 30 minutes.
getChartData() {
this.http
.get('http://localhost:3001/transactions/' + sessionStorage.getItem('id'))
.toPromise()
.then((data: any) => {
this.data = data;
});
}
<button (click)="getChartData()">click</button>
Error :
TypeError: undefined is not an object (evaluating 'this.http.get')

You have to return something from your function. With your current code example, If you hover your mouse over the function name, you'll see it says void.
Also, I recommend using observables rather than promises, Angular uses heavily
getChartData() {
// return the HTTP response
return this.http.get(
'http://localhost:3001/transactions/'
+ sessionStorage.getItem('id'))
}
Then simply, subscribe to it to get the response back
someFunction() {
this.service.getChartData().subscribe((response) => console.log(response))
}

Related

SyntaxError: await is only valid in async function AND TypeError: Cannot read property 'length' of undefined

I have tried to get a result but I can't find how to solve SyntaxError: await is only valid in async function
static async searchYoutube(query, message, voiceChannel) {
await youtube.searchVideos(query, 5).catch(videos => {
await message.say(
':x: There was a problem searching the video you requested!'
);
return;
});
if (videos.length < 5 || !videos) {
message.say(
`:x: I had some trouble finding what you were looking for, please try again or be more specific.`
);
return;
}
Now, they also recommended color async on the front, I did it but it marks another error
TypeError: Cannot read property 'length' of undefined
static async searchYoutube(query, message, voiceChannel) {
await youtube.searchVideos(query, 5).catch(async (videos) => {
await message.say(
':x: There was a problem searching the video you requested!'
);
return;
});
if (videos.length < 5 || !videos) {
message.say(
`:x: I had some trouble finding what you were looking for, please try again or be more specific.`
);
return;
}
Ad SyntaxError: await is only valid in async function – this is pretty much self explanatory error, however, there's no need to await for message.say(...) in either of these cases.
Ad TypeError: Cannot read property 'length' of undefined – this is because videos on line 8 is not defined anywhere but inside (and only inside of) that .catch block.
I'd recommend using .then block same way you use .catch in order to process searchVideos results. The code is asynchronous (is run concurrently), but the wrapper function itself doesn't need to be async.
static searchYoutube(query, message, voiceChannel) {
youtube.searchVideos(query, 5)
.then(videos => {
if (!videos || videos.length < 5) // first check !videos, then videos.length
message.say(`:x: I had some trouble finding what you were looking for, please try again or be more specific.`)
else {
... // continue your code
}
})
.catch(error => { // catch gives an error, not the result
message.say(':x: There was a problem searching the video you requested!')
})
}

Doing something after "redirect" in Cloud Function?

I would like to write to DB after i redirect a user:
exports.contentServer = functions.https.onRequest((request, response) => {
...
...
return response.redirect(finalUrl + "front?action=" + action )
.then(function(){ // **** error : .then of undefined
....
I get an error in the promise.
Cannot read property 'then' of undefined
at exports.contentServer.functions.https.onRequest
As far as I can tell redirect doesn't return a Promise. In fact, from the undefined in your error message it seems like it doesn't return anything at all. The documentation also doesn't show any return value: https://expressjs.com/en/api.html#res.redirect
If it were to return something, you could capture that value and return it later:
const result = response.redirect(finalUrl + "front?action=" + action )
....
return result;

Trouble with Promise and Async functions

I am trying to use promises and async functions to send chunks of an array to an api call that inserts them into a DB. I am trying to get the top function to chunk the array and await for the backend to finsih then it will move on to the next chunk. It errors out after the first iteration. Any ideas??
async chunkArray(arr) {
let len = arr.length
let update_arr
let i = 1
for(i; i<=len; i++) {
if((i%125) === 0) {
update_arr = arr.slice(i-125,i)
await this.updateChuckArray(update_arr)
} else if(i === len) {
let div = (Math.floor(len/125) * 125)
update_arr = arr.slice(div, len)
await this.updateChuckArray(update_arr)
}
}
},
updateChuckArray(update) {
return new Promise(resolve => {
this.$http.put(`/route`, update).then(res => {
res.data.error ? this.$root.updateError(res.data.error) : this.$root.updateSuccess(res.data.message)
}).catch(error => {
this.$root.updateError(res.data.error)
})
})
}
First off your updateChuckArray() never resolves the promise it returns (you never call resolve()).
Instead of manually wrapping a new promise around your function call (that is a promise anti-pattern), you can just return the promise you already have and write it like this:
updateChuckArray(update) {
return this.$http.put(`/route`, update).then(res => {
res.data.error ? this.$root.updateError(res.data.error) : this.$root.updateSuccess(res.data.message);
}).catch(error => {
this.$root.updateError(error);
})
}
FYI, it's unclear what your error handling strategy is. The way you wrote the code (which is followed above), you catch an error from this.$http.put() and handle it and let the loop continue. If that's what you want, this will work. If you want the for loop to abort on error, then you need to rethrow the error in the .catch() handler so the error gets back to the await.
Also, not that in your .catch() handler, you were doing this:
this.$root.updateError(res.data.error)
but there is no res defined there. The error is in error. You would need to use that in order to report the error. I'm not sure what the structure of the error object is here or what exactly you pass to $.root.updateError(), but it must be something that comes from the error object, not an object named res.

Cannot read property 'catch' of undefined

I am trying to use Argon2 encryption in Node, but when I try to encrypt a string, I get this error:
Cannot read property 'catch' of undefined
I have tried handling the errors from the promise returned by the argon2.hash function, but it still does not work.
This is my code so far:
argon2.hash('password', {type: argon2.argon2id})
.then(hash => {
// do something with the hash
}).catch(err => {
// Handle the error
});
Could anyone please help me with fixing this error?
In my case I got that error message because I
a) spied on some async method
spyOn(sut,'myAsyncMethod')
b) later appended .catch() to the original method call and forgot to extend the spy to return a value/promise.
Returning a promise from the spy solved my issue:
spyOn(sut,'myAsyncMethod').and.returnValue(new Promise(resolve=>resolve()));
It throws an exception, it does not return a promise. As such, there is no promise object on which the then(…).catch(…) methods could be invoked.
To catch it, you would need an actual try/catch block
from argon2 github page, you should do this:
const argon2 = require('argon2');
try {
const hash = await argon2.hash("password");
} catch (err) {
//...
}
Try the following instead:
argon2.hash('password', {type: argon2.argon2id})
.then(hash => {
// do something with the hash
}, err => {
// Handle the error
});
The second parameter to a then clause is the onError handler.

How to return a value from a function that uses 'http.get()' method in Node.js?

I have a simple HTTP GET function that only needs to return the response in a function, but right now this function is returning void.
The code in sitechecks.js
var checkSite = () => {
https.get('https://itmagazin.info', (res, err) => {
if (res.statusCode === 200 && res.statusMessage === 'OK') {
return `The site returned: ${res.statusMessage}`
} else return `Error, the site returned: ${err.message}`
})
}
module.exports = checkSite
And when I import the module in index.js, the console returns [Function: checkSite] and not the value itself.
// Index.js
var extSiteCheck = require('./sitechecks')
// This console prints [Function: checkSite] instead of "OK"
console.log(extSiteCheck.checkSite)
However, if I add the return statement on http.get() in the function, the console prints undefined. So I thought that this undefined is a progress, but I don't understand why does it return undefined?
(return http.get() in the checkSite function)
Any help, tips is appreciated.
Because callbacks in JavaScript are asynchronous, you can't return from within a callback.
That means this
console.log(extSiteCheck.checkSite)
runs before the request comes back.
You can try console logging within your callback (instead of trying to return a value), in order to see this in practice. But basically, whatever you are trying to achieve with the results of your get request, you need to do inside the callback.
mebbe something like ... console.log( extSiteCheck.checkSite() );

Resources