Getting data from nested .then function [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
Long story short. I'm trying to learn javascript. And i've been googling for about 4 hours straight right now. And i cant find the answer to my current problem, so i'm assuming i'm looking at this the wrong way.
I'm trying to create a slackbot. The bot is connected, and can look for messages so that part is working.
I've (tried to)create(ed) a function that gets the userID of everynew message based on the name i set in. In my mind this function returns the userID, and that i can later down the code check if userID is in message.text, if it is do something.
I'm assuming it has something to do with that .then function. Can i even return data from that .then function? or can u just use that data inside of that function.
I have several return functions as i was trying to just return it from wherever u could.
function getuserid(botname){
var id = ''
var getbotid = bot.getUsers();
getbotid.then(function(value){
for(var i=0;i<value.members.length;i++){
if(value.members[i].name == botname){
id = value.members[i].id
console.log(id);//this logs what i want.
return id
}
} return id
})
return id
}
var botid = getuserid('jokester');
console.log(botid);

I'm not sure but in my experience, if you return getbotid() then actually you return a promise and you can use it .
function getuserid(botname){
var id = ''
//************Here I return getbotid
return bot.getUsers().then(function(value){
for(var i=0;i<value.members.length;i++){
if(value.members[i].name == botname){
id = value.members[i].id
console.log(id);//this logs what i want.
return id
}
} return id
})
return id
}
//Now you can use it
getuserid('jokester').then(id => console.log(botid));

Related

Problem when converting the output of Fetch to string (Javascript) [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
I have a txt file containing a list of all Italian words (link) that I want to read and then convert to an array of words, but I'm a bit stuck on the reading part. The file was originally downloaded from the web, so it might or might not have some encoding issues.
To read the file, I am using Fetch, with the same code suggested in the top answer of this post. After reading it, if I use alert(storedText) the text is correctly displayed; however, if I try var s = storedText.toString() and then alert(s) I get "undefined" in the alert box.
I guess there is some problem when reading the file, but I'm rather new to JavaScript and I can't figure out what exactly the problem is. Do you guys have any idea?
Edit: this is my full code
var storedText;
fetch('http://doodlemarty.unaux.com/wp-content/uploads/2021/08/parole.txt')
.then(function(response) {
response.setContentType("text/html;charset=UTF-8");
response.text().then(function(text) {
storedText = text;
done();
});
});
var s = storedText.toString();
var fullList = storedText.split('\n');
function test () {
//first try:
alert(storedText);
//second try:
alert(s);
//trying split:
alert(fullList[2]);
};
I have the test function execute when a button is clicked.
This seems like a async issue with promises. You are trying to access storedText before its value is updated in the fetch operation.
Try this:
var storedText;
var s;
var fullList;
async function callFetch() {
let response = await fetch('http://doodlemarty.unaux.com/wp-content/uploads/2021/08/parole.txt')
response.setContentType("text/html;charset=UTF-8");
let text = await response.text();
storedText = text;
}
function setVariables() {
s = storedText.toString();
fullList = storedText.split('\n');
}
async function test() {
await callFetch();
setVariables();
//first try:
alert(storedText);
//second try:
alert(s);
//trying split:
alert(fullList[2]);
};

Calling a function that is defined in a fetch from elsewhere outside of the fetch [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
I'm currently having issues figuring out how to call a function that is defined inside an API Fetch responce function. I currently have an API fetch going out to the github API to get a repository tree. It comes back as a JSON file and my code does all of its stuff. The issue is that I have a function that is defined in the fetch (that I would like to call outside of the fetch, so I dont have to "re-fetch" each time), and I cant call it outside of the fetch (its sorta like a function inside a function).
I've looked around online and asked around and I cant seem to find any answers. I'm fairly new to JS (yes I know my code is messy).
Here is a snippet of my current code:
fetch(api_TreeURL)
.then(function(response) {
return response.json()
}).then(function(json) {
function GetSortOrder(prop) {
return function(a, b) {
if (a[prop] > b[prop]) {
return 1;
} else if (a[prop] < b[prop]) {
return -1;
}
return 0;
}
}
function DELTA_location(currrentlLocation) {
var parentlocation = document.getElementById("delta");
var dirLocation = document.createElement("div")
var dirLocationText = document.createElementNS("http://www.w3.org/1999/xhtml","a")
var lastChar = currrentlLocation.substr(-1);
parentlocation.append(dirLocation)
dirLocation.append(dirLocationText)
dirLocation.setAttribute("class","delta-location")
if (lastChar != '/') {
currrentlLocation = currrentlLocation + '/';
}
dirLocationText.innerHTML = currrentlLocation
}
}).catch(function(ex) {
console.log('parsing failed', ex)
})
If I try and call DELTA_location("") from anywhere outside of the fetch, eg;
fetch(api_TreeURL)
"...the code..."
})
DELTA_location("test")
It will return the error: Uncaught ReferenceError: DELTA_fetch is not defined
Same if I call it from a button in the HTML file.
If you would like to view all of the code, vist the Github
what you can do is use a reference to the function eg :
Outside the fetch code you write
let DELTA_location_ref = (a) => console.warn('Function not fetched yet');
then inside the fetch code you overwrite this variable as :
DELTA_location_ref = (currrentlLocation) => {
var parentlocation = document.getElementById("delta");
var dirLocation = document.createElement("div")
var dirLocationText = document.createElementNS("http://www.w3.org/1999/xhtml","a")
var lastChar = currrentlLocation.substr(-1);
parentlocation.append(dirLocation)
dirLocation.append(dirLocationText)
dirLocation.setAttribute("class","delta-location")
if (lastChar != '/') {
currrentlLocation = currrentlLocation + '/';
}
dirLocationText.innerHTML = currrentlLocation
}
using closures (arrow functions) is important here because you want to have access to the context of the fetch when called from outside
Note that you delta location function does not use the return of the fetch (the json variable) so i don't know why you define it there

Passing values from one promise to the next [duplicate]

This question already has answers here:
How do I access previous promise results in a .then() chain?
(17 answers)
Closed 5 years ago.
A bit new to javascript.
Been dealing with promises, however ran into a problem i dont know how to approach.
How can i pass a value into the next promise resolve?
Here's my code
bot.on('ask.add_account_password', (msg) => {
let username = users[msg.from.id].username;
let password = msg.text;
var accounts = require('./inc/account.js');
accounts.login_account(username,password).then(function(data){
var account = data.params;
console.log(account);
return accounts.store(msg.from.id,username,password,account.followerCount);
}).then(function(data){
let caption = "Your account "+account.username+"("+account.fullName+")has been added\n";
return bot.sendPhoto(msg.from.id, account.picture, {caption:caption});
})
.catch(function(error){
console.log(error);
add_account(msg,error.name);
});
});
On the line where i create the caption variable, i'm trying to access the account object created in the block before it(var account = data.params) but i get a reference error saying its not defined. Now i can easily bypass this by just sending the entire object into the accounts.store function and have it resolve the object when done, but that just seems like a dirty workaround to a bigger problem. Is there a cleaner way to do this?
You can create variable (and set it in promise) in main function or you can return this as result of first promise instead of result from function store
account is undefined at second .then(), use data to reference the Promise value accounts.store returned from previous .then()
.then(function(data) {
// `data` : `accounts.store` returned from previous `.then()`
let caption = "Your account " + data.username
+ "(" + data.fullName + ")has been added\n";
return bot.sendPhoto(msg.from.id, data.picture, {caption:caption});
})
You can pass it in an array and use destructuring in the arguments to unpack the array.
accounts.login_account(username,password).then(function(data){
var account = data.params;
console.log(account);
return [account, accounts.store(msg.from.id,username,password,account.followerCount)];
}).then(function([account, data]){
let caption = "Your account "+account.username+"("+account.fullName+")has been added\n";
return bot.sendPhoto(msg.from.id, account.picture, {caption:caption});
})
You don't actually appear to be using data, so you could just return account after calling store

JavaScript setting public variable [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I have a question regarding setting 'public' variable in JavaScript. Here is my code:
var storeKey;
firebase.database().ref('stores').orderByChild('storeAddress').equalTo('Blk 167').once('value', function(snapshot) {
var storeData = snapshot.val();
if (storeData){
console.log('exists');
}else{
storeKey = firebase.database().ref('stores').push({
storeName : "store1",
storeAddress : "Blk 167"
}).getKey();
//console.log("STORE " + storeKey);
}
});
console.log("STORE " + storeKey);
I am checking if the address exists before adding new record into Firebase. However, if I put the console.log at the last line, I get undefined. It only returns a value if I print it out inside the else statement.
I wanted to separate the storeKey out before I need that data in other places and I don't want my code to be nested inside the else statement. Any idea how to achieve this?
Your function accepts a callback, the console.log is called before the callback, that's why its undefined One way to "solve" it is using promises. e.g.
const deferred = q.defer();
firebase.database().ref('stores').orderByChild('storeAddress').equalTo('Blk 167').once('value', function(snapshot) {
var storeData = snapshot.val();
if (storeData){
console.log('exists');
}else{
storeKey = firebase.database().ref('stores').push({
storeName : "store1",
storeAddress : "Blk 167"
}).getKey();
deferred.resolve(storeKey);
}
});
deferred.then(console.log)

Adding value to javascript Array from json file [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
can you please tell me what i am doing wrong here. i know its simple problem but took whole day for this.
all i was trying to do was adding a value to array called messages from json file.
function get_message(params) {
var messages = ["hello", "bb"]; // i have manually assigned the value here for testing purpose
$.getJSON("messages.json", function( json ) {
var test="JSON Data: " + json.login.loginsuccess.excited.en[0] ; // this is working fine. just retrieving 1 value for testing
console.log(test); // it shows the output get from json file. this line is also fine
messages.push(test);// here is the problem. why i am not being able to add value to this array messages?
});
alert(messages[2]);// it gives me out put undefined
var index = Math.floor(Math.random() * messages.length);
return messages[index];
}
thanks
It's because the AJAX call is asynchronous, so the alert() line is firing before the data is pushed to the messages array. Try moving your code to show the alert inside the callback function.
getJson is asynchronous, so you need to ensure that you're not checking the messages array too soon. You should probably use a callback to get the information you need.
function get_message(params, callback) {
var messages = ["hello", "bb"];
$.getJSON("messages.json", function( json ) {
var test="JSON Data: " + json.login.loginsuccess.excited.en[0];
console.log(test);
messages.push(test);
alert(messages[2]);
var index = Math.floor(Math.random() * messages.length);
callback(messages[index]);
});
}
And use like:
get_message(params, function (data) {
console.log(data);
});

Categories