Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Shaman Tank Spec
Dec 26, 2003

*blep*



I'm wrestling with SocketIO's uploader module, socket.io-file. I'm running the latest version, and uploading files works fine, except I can't for the life of me get the "rename before upload" functionality working.

This is the relevant server side code:
code:
var uploader = new SocketIOFile(socket, {
    uploadDir: {
      images: 'council_images',
      files: 'files'},
    rename: function(filename, fileInfo){
        var file = path.parse(filename);
        var fname = file.name;
        var ext = file.ext;
        console.log("Renaming to " + fname + ext);
        return `${fname}.+${ext}`;
    },			// simple directory
    maxFileSize: 4194304, 	// 4 MB.
    chunkSize: 10240,				// default is 10240(1KB)
    transmissionDelay: 0,		// delay of each transmission, higher value saves more cpu resources, lower upload speed. default is 0(no delay)
    overwrite: true	// overwrite file if exists, default is true.
  });
And here it is being called from the client side:
code:
$('#save_images_btn').click(function(ev){
  ev.preventDefault();
  var fileE2 = document.getElementById("image_input");
  var fn = fileE2.files[0]["name"];
  let file_id = makeid(8);
  console.log("Rename set to: " + file_id + "." + fn.split('.')[1]);
  uploaded_header = file_id + "." + fn.split('.')[1];
  let uploadIds = uploader.upload(fileE2, {
    rename: file_id + "." + fn.split('.')[1],
    uploadTo: "images",
    data: {
      "id": file_id,
      "filename": fn,
      "council": council_id,
      "uploader": window.sessionStorage.getItem('logged_in')
    }
  });
The rename function on server side _is_ being triggered, because the console.log event is appearing in my server's output, but for some reason the file is not being renamed. Both the server and client rename functionality are pretty directly from socket.io-file's piss poor documentation, and looking at the socket.io-file source code itself, this should be extremely simple: if there's a this.rename tag in the upload, socket.io-file should overwrite "filename" with the this.rename value. But it doesn't.

E: I've also tried without the rename block in the server code. No difference.

Shaman Tank Spec fucked around with this message at 16:29 on Jun 29, 2020

Adbot
ADBOT LOVES YOU

Impotence
Nov 8, 2010
Lipstick Apathy
code:
        return `${fname}.+${ext}`;
What's up with the + on this?

Shaman Tank Spec
Dec 26, 2003

*blep*



Biowarfare posted:

code:
        return `${fname}.+${ext}`;
What's up with the + on this?

Good catch, it was in the original example code and must have been left in.

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself

drainpipe posted:

Thanks, but I'm using the vanilla tsc, not babel. I'm not familiar with the javascript/node environment, and all the tools is honestly kinda overwhelming. I had read that Webpack was also something I could have used for this. Is there a tldr rundown of all these tools?

yep so since TypeScript comes with it's own compiler that works fine. I recommend going this way

* Use Babel to transpile your JS code to ES5, rather than the TypeScript compiler

reason being, Babel is compatible with more build tools, there's more plugins, and it's just got more love overall.

* Use the TSC to create your type declaration files (the .d.ts files)

This is really only if you're creating a library, rather than a web app, but this is as simple as adding this to your .tsconfig file: "emitDeclarationOnly": true

* Use webpack to bundle all your code into one index.js file and use HTML webpack plugin to automatically inject the JS file into index.html

https://webpack.js.org/plugins/html-webpack-plugin/

False Toaster
Dec 29, 2006

Stupidity, its both physically and mentally painful.
I’d really like to add some dynamic graphics to a website that show the different pieces of a program. I wanted to do something similar to what you see on this page: [url]https://ubuntupathways.org/how-we-help[/ur] If you scroll down to "Pathways Out of Poverty" you can click item 1-4 and the graphic changes to show different paths. I analyzed and inspected the item and it's coded out of JS. Just trying to figure out what it is exactly. Any tips on how to reproduce this on a website using Squarespace?

Volguus
Mar 3, 2009

False Toaster posted:

I’d really like to add some dynamic graphics to a website that show the different pieces of a program. I wanted to do something similar to what you see on this page: [url]https://ubuntupathways.org/how-we-help[/ur] If you scroll down to "Pathways Out of Poverty" you can click item 1-4 and the graphic changes to show different paths. I analyzed and inspected the item and it's coded out of JS. Just trying to figure out what it is exactly. Any tips on how to reproduce this on a website using Squarespace?

What they do there can be accomplished with plain images. But if you want something more interactive, you can use the canvas element with a bit of JS code to actually do the drawing. One tutorial I found is this: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?
You could also use svg for this kind of thing. SVG can be inlined into HTML, and you can generate it with javascript and style it with CSS. It's also pretty straightforward to write, on par with canvas.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
You could also consider "Lottie", which is a fairly simple json-encoded thing and a library for animating it, or Rive/Flare which is a more heavyweight library and file format.

I prefer direct canvas commands myself because it's easier to do loops and things in the animation and you don't really have to learn anything new, but Lottie/Flare are probably better if you're more designer than programmer.

Tea Bone
Feb 18, 2011

I'm going for gasps.
I'm not sure if this is a javascript question or a CSS question, but I have a div with overflow-y: scroll set on it. At the bottom of the div I have an element which appears/disappears with a transition on max-height.
Something like this:
code:
<div id='window'>
	<div>Window content....</div>
	<div id='transition-box class='closed''>This should show/hide with a transition</div>
</div>

<style>
	#window{
		overflow-y: scroll
	}

	#transition-box{
		max-height:500px;
		transition-property: all;
    		transition-duration: .2s;
		overflow:hidden;
	}

	#transition-box.closed{
		max-height: 0;
		opacity:0;
	}
</style>

<script>

	function show_box(){
		var container = document.getElementsById("window");
		container.scrollTop = container.scrollHeight
		$('#transition-box').removeClass('closed')
	}

	function hide_box(){
		$('#transition-box').addClass('closed')
	}

</script>

The window should automatically scroll to the bottom when transition-box shows if it's not already at that scroll point. If I remove the transition from the CSS everything works perfectly, but if I leave the transition there, the window scrolls to the bottom but the transition happens off screen outside the overflow (I assume this is because "contianer.scrollHeight" is calculated before 'transition-box's size has changed). The weird thing is, if I manually scroll to the bottom of the window, then trigger show_box() the transition happens on screen as expected.

I've tried triggering the automatic scroll after the transition is complete, but obviously then you miss the transition animation.

Sous Videodrome
Apr 9, 2020

I know this thread is dead, but I wrote a beginner tutorial. It walks you through creating a simple express server that adds meme text to images. The tutorial also shows how to host the app on heroku



https://jacobwicks.github.io/2020/08/10/make-memes-with-express-and-canvas.html

Is there a more lively javascript thread on the forums somewhere?

Sous Videodrome fucked around with this message at 03:28 on Aug 11, 2020

The Fool
Oct 16, 2003


You could share it in the newbie programming thread if you wanted. But this thread is far from dead and a handful of people seem to have it bookmarked in order to respond to questions.

Osmosisch
Sep 9, 2007

I shall make everyone look like me! Then when they trick each other, they will say "oh that Coyote, he is the smartest one, he can even trick the great Coyote."



Grimey Drawer

Sous Videodrome posted:

I know this thread is dead, but I wrote a beginner tutorial. It walks you through creating a simple express server that adds meme text to images. The tutorial also shows how to host the app on heroku

https://jacobwicks.github.io/2020/08/10/make-memes-with-express-and-canvas.html

Is there a more lively javascript thread on the forums somewhere?

Very nice work. I feel like you pass a bit too quickly over some concepts like async/await which can be confusing, but it's a great jumping-off point for people to go learn about such things from. It reads a bit like something written by someone who's gotten far enough into a subject that they've forgotten what was initally difficult for them, if you see what I mean.

Somehow discussion of javascript is more diffuse across other threads rather than concentrated here (and mostly consists of disparaging / complaining, often justifiably).

Sous Videodrome
Apr 9, 2020

Thanks for the feedback. I try to strike a balance between explaining everything and keeping blog posts concise enough that people are actually willing to read through it. I wrote the code that lets me add comments to individual lines of code on my Jekyll blog so I could add more detail about specific concepts without distracting from the main concepts. I feel like my writing tends to get too far into unpacking stuff like that, which can make it difficult to follow. So I was trying to pull back from that because shorter stuff seems to get read more. Maybe in addition to linking the documentation on Async/Await I'll add a link to a good post explaining it.

MrMoo
Sep 14, 2000

Anyone with a positive experience with JS physics engines? They all seem to be abandoned for multiple years and various levels of cruft. The most egregious issue appears to be wanting to be the dominant API for everything instead of integrating into third party 3D engines when necessary.

I was after a basic swinging hinge dynamic, and the one engine I found not overly terrible, completely broke when changing basic parameters such as size of the objects. Actually kind of impressive how it could be so bad.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

MrMoo posted:

Anyone with a positive experience with JS physics engines? They all seem to be abandoned for multiple years and various levels of cruft.
Abandoned for years could be a good thing - you don't need a physics engine to be changing all the time. If it was fully debugged three years ago it *should* be abandoned since then.

Box2djs was reasonably good at letting you hook in your own choice of rendering etc. last time I looked, though it does still want to be fully in charge of the physics dimension.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
if you want a basic hinge/swing, coding it up from scratch might be easier than making a physics engine do your bidding

MrMoo
Sep 14, 2000

The idea was to start with something basic and expand as necessary on other projects. Being a sledgehammer was expected.

joebuddah
Jan 30, 2005
I am working a node.js /node red project. What I am trying to do is get the items found in the promise to append to array so that once it has stopped running I can return the entire thing as a json value

code:
// the result I am looking for
[{ ip: '192.168.0.3', name: 'Den' },
{ ip: '192.168.0.4', name: 'Kitchen' }]

code:
function findThem(){

const { Client } = require('tplink-smarthome-api');
 
const client = new Client();
var hostInfo = [];

// Look for devices, log to console, and turn them on
client.startDiscovery().on('device-new', (device) => {

// get ip address
var host = device['host'];
 // device nick name;
var deviceName = device['alias'];
var c = {"ip":host,"name":deviceName}; 
console.log(c);

});
  

 }

the var "c" has the correct value but I am stuck how to get the values out of the promise


this is documentation

https://www.npmjs.com/package/tplink-smarthome-api#Client+stopDiscovery

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

joebuddah posted:

I am working a node.js /node red project. What I am trying to do is get the items found in the promise to append to array so that once it has stopped running I can return the entire thing as a json value

code:
// the result I am looking for
[{ ip: '192.168.0.3', name: 'Den' },
{ ip: '192.168.0.4', name: 'Kitchen' }]

code:
function findThem(){

const { Client } = require('tplink-smarthome-api');
 
const client = new Client();
var hostInfo = [];

// Look for devices, log to console, and turn them on
client.startDiscovery().on('device-new', (device) => {

// get ip address
var host = device['host'];
 // device nick name;
var deviceName = device['alias'];
var c = {"ip":host,"name":deviceName}; 
console.log(c);

});
  

 }

the var "c" has the correct value but I am stuck how to get the values out of the promise


this is documentation

https://www.npmjs.com/package/tplink-smarthome-api#Client+stopDiscovery

What do you mean "get the values out of the promise"? The method you are calling doesn't look like a promise, it's an event listener that calls the function you pass in when a new device is added.

JavaScript code:
const { Client } = require('tplink-smarthome-api');
const client = new Client();

const listOfDevices = [];

client.startDiscovery().on('device-new', (device) => {
 listOfDevices.push( {ip: device.host, name: device.alias} ); 
});
  
You then have to call client.stopDiscovery() to get it to stop listening for new devices.

EDIT: Looks like when you create a client, you can just get the devices ( https://plasticrake.github.io/tplink-smarthome-api/classes/client.html#devices ) property to get a Map of the devices apparently, so you can just get it as a one-off and then kill the client.

Lumpy fucked around with this message at 22:01 on Aug 15, 2020

Ruggan
Feb 20, 2007
WHAT THAT SMELL LIKE?!


??

code:
function doSomethingWithThem(things) {
// get ip address
var host = device['host'];
 // device nick name;
var deviceName = device['alias'];
var c = {"ip":host,"name":deviceName};  
// whatever else you need to do
}

function findThem(){

const { Client } = require('tplink-smarthome-api');
 
const client = new Client();
var hostInfo = [];

// Look for devices, log to console, and turn them on
client.startDiscovery().on('device-new', (device) => {

    doSomethingWithThem(device);

});
  

 }

Callback function in promise to do something with them

Or maybe use async await, and await the result of the function

Same as how you do stuff from a fetch call to do stuff with results from an api, really.

Ruggan
Feb 20, 2007
WHAT THAT SMELL LIKE?!


Lumpy posted:

What do you mean "get the values our of the promise"? The method you are calling doesn't look like a promise, it's an event listener that calls the function you pass in when a new device is added.

JavaScript code:
const { Client } = require('tplink-smarthome-api');
const client = new Client();

const listOfDevices = [];

client.startDiscovery().on('device-new', (device) => {
 listOfDevices.push( {ip: device.host, name: device.alias} ); 
});
  
You then have to call client.stopDiscovery() to get it to stop listening for new devices.

Or that, if the on isn’t a glorified .then()

joebuddah
Jan 30, 2005
Thanks for the help. The issue was I wasn't waiting long enough for the discovery to stop automatically. Since I only have two devices, I set it to stop when it found two devices.
Then the push to the array won't show up until after the discovery stopped.

Dancer
May 23, 2011
Is there a way to use different versions/plugins of babel with different files in my project? I'm trying to set up a project with Express + Netlify (reference). By just fiddling with babel I keep switching back and forth between:
code:
Plugin/Preset files are not allowed to export objects, only functions
(because the way to export out of AWS/Netlify functions is exports.modules = [thing] )

and:
code:
Module parse failed: Unexpected token (237:6)
You may need an appropriate loader to handle this file type.

Boz0r
Sep 7, 2006
The Rocketship in action.
I'm trying to use Microsoft Authentication Library to get an Azure token from a web resource written in typescript in Dynamics 365. These web resources are just embedded js files, and I'm not a javascript dev, so I don't know how to pack an npm package into a single js file. Also, when I copy the *.d.ts files to my project the import paths in those files are wrong.

Osmosisch
Sep 9, 2007

I shall make everyone look like me! Then when they trick each other, they will say "oh that Coyote, he is the smartest one, he can even trick the great Coyote."



Grimey Drawer

Boz0r posted:

I'm trying to use Microsoft Authentication Library to get an Azure token from a web resource written in typescript in Dynamics 365. These web resources are just embedded js files, and I'm not a javascript dev, so I don't know how to pack an npm package into a single js file. Also, when I copy the *.d.ts files to my project the import paths in those files are wrong.

Are you writing your own nodejs application, or are you trying to bundle a web application?

Typically if you're copying files around by hand you're doing something unusual, npm or yarn are used to manage dependencies on external code. If you then import from those dependencies it should also automatically grab any type definitions.

If you want to bundle a web application into a single js file, the most common approach is to use webpack.

unpacked robinhood
Feb 18, 2013

by Fluffdaddy
I'm looking for help with someone else's NodeJS code, which I've no experience with.

Here's the part:
JavaScript code:
const commitManyVotes = (params) => {
    return new Promise((resolve, reject) => {
        let pvalues = [params.peoples, params.votes]
        //doing a transaction on a blockchain
        myContract.methods.commitVotes(...pvalues).send({
            // ..snip..
        }, (error, ok) => {
            if (error) {
                let errMsg = 'Error: commitVote call error - ' + error
                logger.error(errMsg);
                reject(errMsg);
            } else {
                logger.debug("1) first i go through here");
                resolve(ok);
            }
        }).catch((err) => {
            logger.debug("2) and then I crash here")
            reject(err);
        })
    })
};
My problem is sometimes the transaction will fail, which results in the code going succesively through 1) and 2).
How should I refactor this to handle that situation through a single statement, instead of that weird two part thing ?

e:this isn't bitcoin of anything where it can do a lot of damage fortunetaly

unpacked robinhood fucked around with this message at 14:55 on Aug 27, 2020

Osmosisch
Sep 9, 2007

I shall make everyone look like me! Then when they trick each other, they will say "oh that Coyote, he is the smartest one, he can even trick the great Coyote."



Grimey Drawer
I ain't helping with no bitcoin

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

unpacked robinhood posted:

My problem is sometimes the transaction will fail, which results in the code going succesively through 1) and 2).
It goes through the non-error path, then the thrown exception path? That's a weird choice.

Also the send function taking an error as the first parameter and ok as the second is weird.

Logging what's caught in the catch might tell you something more useful too.

If not, stick a breakpoint on the first time it enters a path you don't expect it to, and step from there to see how it gets into the catch path.

Doom Mathematic
Sep 2, 2008

unpacked robinhood posted:

I'm looking for help with someone else's NodeJS code, which I've no experience with.

Here's the part:
JavaScript code:
const commitManyVotes = (params) => {
    return new Promise((resolve, reject) => {
        let pvalues = [params.peoples, params.votes]
        //doing a transaction on a blockchain
        myContract.methods.commitVotes(...pvalues).send({
            // ..snip..
        }, (error, ok) => {
            if (error) {
                let errMsg = 'Error: commitVote call error - ' + error
                logger.error(errMsg);
                reject(errMsg);
            } else {
                logger.debug("1) first i go through here");
                resolve(ok);
            }
        }).catch((err) => {
            logger.debug("2) and then I crash here")
            reject(err);
        })
    })
};
My problem is sometimes the transaction will fail, which results in the code going succesively through 1) and 2).
How should I refactor this to handle that situation through a single statement, instead of that weird two part thing ?

e:this isn't bitcoin of anything where it can do a lot of damage fortunetaly

Something rather weird is going on here because the send is simultaneously (1) accepting a callback (error, ok) => { ... } and (2) returning a promise which you can chain .then or .catch onto the end of. send should not do both of these things. It should either use the callback pattern or use promises, you don't mix them together.

It's also very strange that send calls the callback with no error and then returns a promise which rejects. That seems inconsistent to me.

I would suggest looking deeper into how send is implemented and how it's intended to be used. Are you sure you have the signature of the (error, ok) => { ... } callback correct? Are you sure that error is meant to be the transaction failure error? Because it clearly isn't in this case. Are you sure this callback is called after the transaction is completed, not called at some other time for some other reason? What does the documentation for this method say about how it's intended to be used? Is there example code?

Assuming send isn't just buggy, my first guess at this point would be that the callback isn't doing what you think, and you're meant to be using the promise chain only. If that's the case, you don't need to new Promise yourself, so your code can be greatly simplified to something like:

JavaScript code:
const commitManyVotes = (params) => {
    let pvalues = [params.peoples, params.votes]
    //doing a transaction on a blockchain
    return myContract.methods.commitVotes(...pvalues).send({
        // ..snip..
    }, (unknown, args) => {
        // don't know what this is for
    })
        .catch((err) => {
            logger.error(err.message);
            throw err;
        })
};

roomforthetuna posted:

Also the send function taking an error as the first parameter and ok as the second is weird.

This is pretty standard practice for a lot of built-in Node.js APIs, notably the fs package.

unpacked robinhood
Feb 18, 2013

by Fluffdaddy
Thanks you for delving into it, Doom Mathematic

Doom Mathematic posted:

What does the documentation for this method say about how it's intended to be used? Is there example code?
Looking at the docs certainly did help, something I should have done before posting.

Doom Mathematic posted:

Assuming send isn't just buggy, my first guess at this point would be that the callback isn't doing what you think, and you're meant to be using the promise chain only. If that's the case, you don't need to new Promise yourself, so your code can be greatly simplified to something like:

JavaScript code:
..snip..

I restructured my code down to something cleaner that seems to work. I'd rather keep the return new Promise() declarations for now unless it's absolutely bad practice.
Now I'm stuck trying to do add some functionality.
I need to run verify on each element from the params.people array and ignore some items depending on the result, but I can't get the results to resolve in usable form beyond Promise { <pending> }, which I've pasted from the logs in the comments below.
I must be misusing Promise.all() but I can't tell how. (The logs from should_be_accepted() are otherwise consistent with what I expect)

JavaScript code:
function should_be_accepted(params) {
    return Promise.all(params.map((person) => {
        verify(person).then((result) => {
            logger.debug("keep them: ", person);
        }).catch((err) => {
            logger.error("ignore them: ", person)
        });
    }))
};

const verify = (params) => {
    return new Promise((resolve, reject) => {
      //...
    }
  )
};

const commitManyVotes = (params) => {
    return new Promise((resolve, reject) => {
        let to_do_list = should_be_accepted(params.peoples)
        to_do_list.then(results => logger.debug("acceptable", results)).catch((err) => {
            logger.error(err)
        })
         //>  (to_do_list.then.results) acceptable [ undefined, undefined ]
        logger.debug("TODOLIST", to_do_list)
        // TODOLIST Promise { <pending> }
        let pvalues = [params.peoples, params.votes]
        //doing a transaction on a blockchain
        myContract.methods.commitVotes(...pvalues).send({
                // ..snip..
            })
            .on('receipt', function(receipt) {
                resolve(receipt.transactionHash)
            })
            .on('error', function(error) {
                // logger.debug(error)
                reject(error)
            })
    })
};


unpacked robinhood fucked around with this message at 11:23 on Sep 1, 2020

Granite Octopus
Jun 24, 2008

What you're missing is that Promises.all() just returns another promise, which hasn't actually resolved yet.

If you just chuck in an await line, it will wait for the Promises.all() promise (and all the promises contained within) to resolve before continuing. After that, you should get an array with the results of each promise as each member.

code:
        let to_do_list = should_be_accepted(params.peoples)
        to_do_list.then(results => logger.debug("acceptable", results)).catch((err) => {
            logger.error(err)
        })
        await to_do_list;
         //>  (to_do_list.then.results) acceptable [ undefined, undefined ]
        logger.debug("TODOLIST", to_do_list)
You'll also need to mark the containing function as async but I assume you already know that.

That answers your primary question, but it doesn't really address some other structural changes that you should probably make.

Instead of "awaiting" that promise then continuing on in the async style, you should probably chuck all that other blockchain logic in the then() (or pass it in as a function) as that keeps some level of consistency. What you are doing now is good for understanding but you'll want to condense it down as you get more confident.

Granite Octopus fucked around with this message at 12:37 on Sep 1, 2020

unpacked robinhood
Feb 18, 2013

by Fluffdaddy

Granite Octopus posted:

What you're missing is that Promises.all() just returns another promise, which hasn't actually resolved yet.

If you just chuck in an await line, it will wait for the Promises.all() promise (and all the promises contained within) to resolve before continuing. After that, you should get an array with the results of each promise as each member.

You'll also need to mark the containing function as async but I assume you already know that.

That answers your primary question

I've tried a number of combinations inspired by the content here and here but none worked. This is my current attempt:
JavaScript code:
const commitManyVotes = async (params) => {
    return new Promise((resolve, reject) => {
        const to_do_list = await should_be_accepted(params.peoples)
    })
};
What would be the correct version ?

Granite Octopus posted:

Instead of "awaiting" that promise then continuing on in the async style, you should probably chuck all that other blockchain logic in the then() (or pass it in as a function) as that keeps some level of consistency. What you are doing now is good for understanding but you'll want to condense it down as you get more confident.

Thanks, I'd like to pare down that code once I've got something functional so your directions are appreciated.

Doom Mathematic
Sep 2, 2008
One minor you may have is that there is a critical keyword missing here:

unpacked robinhood posted:

JavaScript code:
function should_be_accepted(params) {
    return Promise.all(params.map((person) => {
        verify(person).then((result) => {
            logger.debug("keep them: ", person);
        }).catch((err) => {
            logger.error("ignore them: ", person)
        });
    }))
};

Spot the difference between the code above and the fixed code below:

JavaScript code:
function should_be_accepted(params) {
    return Promise.all(params.map((person) => {
        return verify(person).then((result) => {
            logger.debug("keep them: ", person);
        }).catch((err) => {
            logger.error("ignore them: ", person)
        });
    }))
};
Without that extra return, you were essentially doing something like:

JavaScript code:
function should_be_accepted(params) {
    return Promise.all([undefined, undefined, undefined]) // one per entry in `params`
};
This promise then resolves almost immediately - before any of the verify promises have resolved.

Roadie
Jun 30, 2013

unpacked robinhood posted:

I've tried a number of combinations inspired by the content here and here but none worked. This is my current attempt:
JavaScript code:
const commitManyVotes = async (params) => {
    return new Promise((resolve, reject) => {
        const to_do_list = await should_be_accepted(params.peoples)
    })
};
What would be the correct version ?

Your problem here is that when you use async, you're making a function that is, itself, already a de facto promise wrapper. If you use a promise in that you're just nesting everything one level deeper inside that promise's callback instead.

JavaScript code:
/**
 * @typedef ToDoList
 * @type {{ id: number }[]}
 * This might be an array or something, I dunno
 */

/**
 * @returns {Promise<ToDoList>}
 */
const commitManyVotes = async (params) => {
  /** @type {ToDoList} */
  let toDoList = await shouldBeAccepted(params.peoples);

  // ...
  // manipulate toDoList here like a normal variable
  // ...

  // You return here as a ToDoList, but you use .then() on the function to get it as a promise
  return toDoList;
};

commitManyVotes(someParams).then(toDoList => {
  // do stuff here
});

Roadie fucked around with this message at 22:27 on Sep 1, 2020

unpacked robinhood
Feb 18, 2013

by Fluffdaddy
So merging this fix:

Doom Mathematic posted:

Spot the difference between the code above and the fixed code below:

and inspired by:

Roadie posted:

Your problem here is that when you use async, you're making a function that is, itself, already a de facto promise wrapper. If you use a promise in that you're just nesting everything one level deeper inside that promise's callback instead.

I came up with something that lets me acess the data from should_be_accepted from commitManyVotes, but getting rid of the explicit new Promise((resolve, reject).. construct removes the ability to call resolve and reject later, which I don't know how to fix or mimic.

JavaScript code:
function should_be_accepted(params) {
    return Promise.all(params.map((person) => {
        return verify(person)
    }))
}

const verify = (params) => {
    return new Promise((resolve, reject) => {
        //...
    })
};

const commitManyVotes = async (params) => {
    should_be_accepted(params.peoples).then((results) => {
        //'results' is usable here
        //
        //I think the blockchain stuff can be embedded here ?
        //
    })
};

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

unpacked robinhood posted:

I came up with something that lets me acess the data from should_be_accepted from commitManyVotes, but getting rid of the explicit new Promise((resolve, reject).. construct removes the ability to call resolve and reject later, which I don't know how to fix or mimic.
Generally once you go with async syntax, any instances of "Promise" or "then()" are smelly, you should be doing them some other way.

The idiomatic way to do "resolve/reject" with async is return/throw.

Something like:
code:
const commitManyVotes = async (params) => {
  try {
    var results = await should_be_accepted(params.people);
    // Use your results, this is your 'blockchain' place.
  } catch (e) {
    // do error handling or maybe rethrow.
  }
};
(Also it should be noted that actual blockchain stuff, where you're actually doing work, is not a good match for async or Promise, everything will still be blocked by your work, async is not the same as multithreaded.)

Roadie
Jun 30, 2013

roomforthetuna posted:

(Also it should be noted that actual blockchain stuff, where you're actually doing work, is not a good match for async or Promise, everything will still be blocked by your work, async is not the same as multithreaded.)

:yeah:

For any actual multithreaded behavior you need to be looking at web workers or Node worker threads, at which point you have entirely different concerns of message passing and all that.

unpacked robinhood
Feb 18, 2013

by Fluffdaddy

roomforthetuna posted:

(Also it should be noted that actual blockchain stuff, where you're actually doing work, is not a good match for async or Promise, everything will still be blocked by your work, async is not the same as multithreaded.)

Roadie posted:

For any actual multithreaded behavior you need to be looking at web workers or Node worker threads, at which point you have entirely different concerns of message passing and all that.

The guy who wrote this initially used a jobs/worker system which i'd like to put back in at some point. Only issue is I need to report with some status data from the blockchain and can't just say "your stuff is being processed, thank you". Right now it's done the naive way by holding on to the initial connection.

Boz0r
Sep 7, 2006
The Rocketship in action.
For async methods in typescript, is it best practice to use await or .then? Or is that just preference?

Adbot
ADBOT LOVES YOU

necrotic
Aug 2, 2005
I owe my brother big time for this!
If you're labeling the method as async use await. I'd go for async style in general now.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply