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
Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
import * as Foo from './foo'; is what I use but they chose the ugliest import syntax for a really good idea

Adbot
ADBOT LOVES YOU

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!

Suspicious Dish posted:

import * as Foo from './foo'; is what I use but they chose the ugliest import syntax for a really good idea
I don't mind that too much, because it means you can do
code:
import * as Foo from './foo';
Foo.doAThing();
Foo.doAnotherThing();
Foo.doAThirdThing();
in one client file, and then
code:
import {doAThing} from './foo';
doAThing();
in another where you're confident there's no namespace collision and you don't want to import too many things.

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Khorne posted:

The export syntax is a mini-horror in itself.

...

It's baffling until you read about it and their intent. Even then, it's inexplicable why anyone thought not being able to import a default through curly braces was a good idea. Or why they thought only having a single export wouldn't make it automatically the default and then require curly braces, with no default, for modules with more than one export. Or, just always or never require curly braces on imports. Instead, we have what is there now which is unintuitive and awkward.

export behavior and import syntax are definitely annoying to me (I don't use JS for long enough at a time to internalize the rules) and I kind of assume that it is one of the several JS features that got committee'd into a design that is hard to convey concisely because it's actually a melding of disparate approaches to how the feature should work.

Suspicious Dish posted:

import * as Foo from './foo'; is what I use but they chose the ugliest import syntax for a really good idea

yep, that pattern (individual exports + import * as Modulename or import {few, things, here}) seems like a really good and flexible way to go, but definitely requires more rather than less syntax gymnastics.

I guess the strongest thing about some of the more complex import syntax is that it is like the syntax for destructuring but ugh.

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!
I've changed my mind, I do dislike
import * as Foo from '...'
because I want the syntax for that to be just
import Foo from '...'

Having a default and individual exports is weird, I expect individual exports to just be combined into the single default exported object, and
import {a, b, c} from '...'
to be essentially interpreted as destructuring that single exported object.

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

roomforthetuna posted:

I expect individual exports to just be combined into the single default exported object, and
import {a, b, c} from '...'
to be essentially interpreted as destructuring that single exported object.

:yossame:

The syntax is fiddly and not good

smackfu
Jun 7, 2004

Our linting rules (which are generally in sync with AirBnb) require you to use the default export if there is only one export from a file. This seems well intentioned but in practice you often add another export in a future commit and then have to change everyplace the original default export was used. Argh.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Khorne posted:

Once you know how it works it's not awful to work with.

Petition for new thread title!

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.
I am glad when I get to use JavaScript for my own amusement and largely write things as one big HTML file. Yes, the browser is a more fun JS environment to program for and things are simpler when you just write ES6 (+/- a little browser variation) rather than having to use a bunch of tooling

Then again this only works because it is for funsies?

e: I wonder if you can write modules-style ES 6 using inline script elements... my head says no but my heart says please be yes.

e^2: aw gently caress yeah, you can put modules in inline script elements! gj whoever put that in the standard

prisoner of waffles fucked around with this message at 15:25 on Sep 17, 2018

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



prisoner of waffles posted:

I am glad when I get to use JavaScript for my own amusement and largely write things as one big HTML file. Yes, the browser is a more fun JS environment to program for and things are simpler when you just write ES6 (+/- a little browser variation) rather than having to use a bunch of tooling

Then again this only works because it is for funsies?

e: I wonder if you can write modules-style ES 6 using inline script elements... my head says no but my heart says please be yes.

e^2: aw gently caress yeah, you can put modules in inline script elements! gj whoever put that in the standard

How do you reference them?

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Munkeymon posted:

How do you reference them?

that is a great fuckin' question and a casual googling does not reveal a direct way, looooolll

e: workarounds: https://stackoverflow.com/questions/43817297/inlining-ecmascript-modules-in-html

"use a serviceworker to auto-fake the existence of an external script from the inline module source" and "create a blob URL and then import from it" are options looooolllll

e^2: yeah, inline modules are kinda useless, whoops, hahaha

prisoner of waffles fucked around with this message at 16:38 on Sep 17, 2018

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
For a while there was planned to be a "Loader" API so you could inject into the module resolution algorithm but then they punted on it. They wanted to have a longer planning time but everybody was using Babel (back then known as 6to5) and Webpack and they included and promoted the feature and invented their own semantics so the committee was stuck with it.

The lack of coordination between WHATWG and TC39, with both sides leaving the host integration to the other, is one of the big reasons that features like that are off the table now.

Fun fact the whole "import file paths" thing was never supposed to be a thing, it was originally planned to be a virtual hierarchy like C#.

Suspicious Dish fucked around with this message at 16:46 on Sep 17, 2018

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Suspicious Dish posted:

For a while there was planned to be a "Loader" API so you could inject into the module resolution algorithm but then they punted on it. They wanted to have a longer planning time but everybody was using Babel (back then known as 6to5) and Webpack and they included and promoted the feature and invented their own semantics so the committee was stuck with it.

The lack of coordination between WHATWG and TC39, with both sides leaving the host integration to the other, is one of the big reasons that features like that are off the table now.

feature development like a game of pingpong where both players just wander off after a while

Suspicious Dish posted:

Fun fact the whole "import file paths" thing was never supposed to be a thing, it was originally planned to be a virtual hierarchy like C#.

hahaha, we could have a clean abstract system that works well and is not tied to a specific implementation but hey let's not

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Suspicious Dish posted:

For a while there was planned to be a "Loader" API so you could inject into the module resolution algorithm but then they punted on it. They wanted to have a longer planning time but everybody was using Babel (back then known as 6to5) and Webpack and they included and promoted the feature and invented their own semantics so the committee was stuck with it.

The lack of coordination between WHATWG and TC39, with both sides leaving the host integration to the other, is one of the big reasons that features like that are off the table now.

Fun fact the whole "import file paths" thing was never supposed to be a thing, it was originally planned to be a virtual hierarchy like C#.

JFC

Chenghiz
Feb 14, 2007

WHITE WHALE
HOLY GRAIL
C#’s implementation really only makes sense because it has a huge IDE to back it up. If you don’t have that helping you out it can be really difficult to tell where a namespace comes from.

At least when you import a method or class from a library in node modules, you know exactly what you got, even if you’re using notepad.

Harriet Carker
Jun 2, 2009

How can I check if devDependencies are used or not? I ran depcheck but I don’t know much about the build process and there are tons of mystery devDependencies that I would obviously feel unsafe removing. There’s nobody I can ask - I’m the only one on the project now. Obviously the thing to do is not touch it - but I’d like to clean up unused ones someday if it’s safe to do so.

huhu
Feb 24, 2006

dantheman650 posted:

How can I check if devDependencies are used or not? I ran depcheck but I don’t know much about the build process and there are tons of mystery devDependencies that I would obviously feel unsafe removing. There’s nobody I can ask - I’m the only one on the project now. Obviously the thing to do is not touch it - but I’d like to clean up unused ones someday if it’s safe to do so.

Not sure what to say if you don't trust depcheck. You could learn what each package does. Or you could delete all the dependencies and keep trying to npm start and then installing the required packages until the site works again.

Knifegrab
Jul 30, 2014

Gadzooks! I'm terrified of this little child who is going to stab me with a knife. I must wrest the knife away from his control and therefore gain the upperhand.
I'm got a dumb question. I love use async/await. However sometimes I want to use async/await but I want to run several async/awaits concurrently as opposed to chaining them together.

How can I do this? If I just do:

code:
let response = await doAThing1();
let response2 = await doAThing2();
Obviously both doAThing1 and doAThing2 return promises and can be awaited, however in the code above, doAThing2() won't be evaluated until the promise resolves on doAThing1(). How do I use async/await to run doAThing1() and doAThing2() at teh same time?

necrotic
Aug 2, 2005
I owe my brother big time for this!
Look at Promise.all.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



I think this is what you want https://stackoverflow.com/a/35612484/301807

JavaScript code:
let [r1, r2] = await Promise.all([someCall(), anotherCall()]);
Something like that

Knifegrab
Jul 30, 2014

Gadzooks! I'm terrified of this little child who is going to stab me with a knife. I must wrest the knife away from his control and therefore gain the upperhand.

necrotic posted:

Look at Promise.all.

But promise all will only resolve all of them or none of them. I want to display things as they come in, not all together at once if that makes sense?

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Knifegrab posted:

But promise all will only resolve all of them or none of them. I want to display things as they come in, not all together at once if that makes sense?

Wrap them in async functions that handle the return data as it comes in. You were probably going to have to do that to handle errors cleanly, anyway.

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

Knifegrab posted:

But promise all will only resolve all of them or none of them. I want to display things as they come in, not all together at once if that makes sense?

idk, some poo poo like this?

code:
Promise.inResolutionOrder_synchronous = function*(promises) {
  let remaining = new Set(promises);
  while(remaining.size > 0) {
    let first = Promise.race(remaining);
    remaining.delete(first);
    yield first;
  }
};
code:
Promise.inResolutionOrder = async function*(promises) {
  let remaining = new Set(promises);
  while(remaining.size > 0) {
    let first = Promise.race(remaining);
    remaining.delete(first);
    yield first;
  }
};
I'll admit that it doesn't make sense that they didn't make something like this as part of promises themselves.

Munkeymon posted:

Wrap them in async functions that handle the return data as it comes in. You were probably going to have to do that to handle errors cleanly, anyway.

You're more familiar with how this stuff works, how would my utility function version of this fall down? Promise.race gives back the "first to resolve" regardless of whether it succeeded or errored and callers of my code would have to take care of that themselves...

SimonChris
Apr 24, 2008

The Baron's daughter is missing, and you are the man to find her. No problem. With your inexhaustible arsenal of hard-boiled similes, there is nothing you can't handle.
Grimey Drawer
Why not just attach a .then() handler to each returned promise, like you normally do with promises? That will run the promises at the same time and handle them as they resolve.

The whole point of async/await is to make it easier to write code where promises are run in sequence. It doesn't seem very well suited to this purpose.

Edit:
code:
doAThing1().then(response => ...);
doAThing2().then(response2 => ...);

SimonChris fucked around with this message at 21:01 on Sep 18, 2018

mystes
May 31, 2006

The question is, Knifegrab, are you trying to do something at the end that requires both of the values in the first place?

Knifegrab
Jul 30, 2014

Gadzooks! I'm terrified of this little child who is going to stab me with a knife. I must wrest the knife away from his control and therefore gain the upperhand.

mystes posted:

The question is, Knifegrab, are you trying to do something at the end that requires both of the values in the first place?

Nope.

SimonChris posted:

Why not just attach a .then() handler to each returned promise, like you normally do with promises? That will run the promises at the same time and handle them as they resolve.

The whole point of async/await is to make it easier to write code where promises are run in sequence. It doesn't seem very well suited to this purpose.

Edit:
code:
doAThing1().then(response => ...);
doAThing2().then(response2 => ...);

Yeah I think I just shouldn't use async/await

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

If you just want to stuff the values from > 1 promise into some sink, then yeah maybe you should create all your promises and call .then(sink) on them

mystes
May 31, 2006

Knifegrab posted:

Nope.


Yeah I think I just shouldn't use async/await
The important thing to keep in mind is that await is just syntactic sugar for passing a callback to promise.then() in the case where the entire remainder of the body of your function is what you want to pass as the callback, so if that isn't what you want, you don't need to use await.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



prisoner of waffles posted:

You're more familiar with how this stuff works, how would my utility function version of this fall down? Promise.race gives back the "first to resolve" regardless of whether it succeeded or errored and callers of my code would have to take care of that themselves...

I was just thinking that it sounded like they want to load two or more remote resources more-or-less simultaneously and in that situation failures ought to be handled individually in some way. Either with a wrapper or by adding error handlers to each promise.

biznatchio
Mar 31, 2001


Buglord

Knifegrab posted:

Yeah I think I just shouldn't use async/await

The key is that you don't *have* to await on an async function call. Just move the self-contained bits you want to operate independently of each other into their own async functions, then fire them all off from a main function that doesn't await on any of them. For example, this kicks off three tasks that each have their own result handling; and all three tasks run concurrently and use await for their result handling.

Knifegrab
Jul 30, 2014

Gadzooks! I'm terrified of this little child who is going to stab me with a knife. I must wrest the knife away from his control and therefore gain the upperhand.

biznatchio posted:

The key is that you don't *have* to await on an async function call. Just move the self-contained bits you want to operate independently of each other into their own async functions, then fire them all off from a main function that doesn't await on any of them. For example, this kicks off three tasks that each have their own result handling; and all three tasks run concurrently and use await for their result handling.

This is awesome, thanks for the example, however I think going with this approach as opposed to just either using promise.all and syncing the results or using promise chains is more a readability/clarity issue.

I want to stubbornly never use promise chains again but not at the cost of convoluted code.

TIP
Mar 21, 2006

Your move, creep.



I've been beating my head against a wall dealing with audio in JavaScript.

I'm writing an app that records vocals from a mic, mixes that with a background music track, and then allows you to save that as an mp3 or ogg file (either is fine, don't have to have both).

Initially I wrote code that would play the background music, record your vocals, and used MediaRecorder to capture both as a stream and save to a file when done.

This is fine, except that I need to be able tweak the volume of the recording and the background music independently after recording.

So I rewrote it to save the recording as an audioBuffer, then convert the music to an audioBuffer, and then create a new buffer where I add their values together. This way I can keep changing the volume of each buffer, and mix them over and over again.

This works, and it sounds good when I use an audioBufferSource to play it back, but I can't figure out how to use that audioBuffer to get a file I can download.

It seems like MediaRecorder is the only built-in functionality for saving audio to file, but it only works in real time, which would be a real pain in the rear end.

Any thoughts?

TIP fucked around with this message at 00:21 on Sep 20, 2018

necrotic
Aug 2, 2005
I owe my brother big time for this!
I think you have to turn it into a wav file on your own, the ArrayBuffers are just raw PCM data. It should be pretty simple to roll your own if you want, or look at something like https://www.npmjs.com/package/audiobuffer-to-wav.

TIP
Mar 21, 2006

Your move, creep.



necrotic posted:

I think you have to turn it into a wav file on your own, the ArrayBuffers are just raw PCM data. It should be pretty simple to roll your own if you want, or look at something like https://www.npmjs.com/package/audiobuffer-to-wav.

AudioBuffers are different from ArrayBuffers, and while it's easy to go from an ArrayBuffer to an AudioBuffer it's really hard to go the other direction (I spent a while trying).

I'm working with AudioBuffers because I need to mix the two signals, which is really easy to do with some simple addition using AudioBuffers, but I don't know how to do it with ArrayBuffers.

But, even if I get it to WAV format, I still need to go from that to ogg or mp3, which seems to involve loading half a meg of JS libraries to do it in a web worker.

I was really hoping to avoid loading tons of JavaScript libraries for this, since the drat built in MediaRecorder can encode ogg/mp3. Really annoying that they limited that to real time encoding of streams.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
yeah the web audio api sucks what's new. failed TAG review but whatwg cant really do anything about that since its already shipping in browsers, thanks chris.

Hypnobeard
Sep 15, 2004

Obey the Beard



Another Jest-related problem, I think.

I'm trying to catch a thrown exception. The test is like so:

code:
  test('negative digit', () => {
    expect(() => {
      converter.convert([1, -1, 1, 0, 1, 0], 2, 10);
    }).toThrow(new Error('Input has wrong format'));
  });
My code in the function has a test that checks for the negative digit, and then throws an error like so:

code:
throw new Error('Input has wrong format');
This ends up being a failure with this message:

code:
expect(function).toThrow(error)

    Expected the function to throw an error matching:
      [Error: Input has wrong format]
    Instead, it threw:
      Error: Input has wrong format
          at Converter.convert (all-your-base.js:6:15)
          at all-your-base.spec.js:62:17
	... <rest of stack trace elided>
How do I get these tests to match up? I *think* I'm throwing the correct error, but it seems to want an array of errors? Doing throw [new Error...]; doesn't seem to produce the desired effect.

What am I doing wrong here?

IAmKale
Jun 7, 2007

やらないか

Fun Shoe

Hypnobeard posted:

What am I doing wrong here?
Don't pass in an instance of an error, just the string you're expecting it to include in the error that gets thrown:

code:
  test('negative digit', () => {
    expect(() => {
      converter.convert([1, -1, 1, 0, 1, 0], 2, 10);
    }).toThrow('Input has wrong format');
  });
This isn't particularly related to your example, but if you're expecting a certain kind of exception, you can alternatively pass in the error class itself:

code:
  test('negative digit', () => {
    expect(() => {
      converter.convert([1, -1, 1, 0, 1, 0], 2, 10);
    }).toThrow(CustomErrorClass);
  });
This is the part of the Jest docs you want: https://jestjs.io/docs/en/expect.html#tothrowerror

Hypnobeard
Sep 15, 2004

Obey the Beard



IAmKale posted:

Don't pass in an instance of an error, just the string you're expecting it to include in the error that gets thrown:

code:
  test('negative digit', () => {
    expect(() => {
      converter.convert([1, -1, 1, 0, 1, 0], 2, 10);
    }).toThrow('Input has wrong format');
  });
This isn't particularly related to your example, but if you're expecting a certain kind of exception, you can alternatively pass in the error class itself:

code:
  test('negative digit', () => {
    expect(() => {
      converter.convert([1, -1, 1, 0, 1, 0], 2, 10);
    }).toThrow(CustomErrorClass);
  });
This is the part of the Jest docs you want: https://jestjs.io/docs/en/expect.html#tothrowerror

These are from exercism.io, so I can't actually modify the spec files. (Well, I *can* modify them but it'll get bounced by the mentor because the tests on their end will fail because they don't have to modified test cases.)

Thinking about it, my question is more "how do I get the error in an Array?"--because the ways I know about don't seem to produce what the test is looking for.

Edit: Jesus I loving hate Javascript already and I don't even know it, really. Most of my tests started magically passing and the others are now failing because of the wrong exception being thrown instead of some weird matching problem.

Hypnobeard fucked around with this message at 18:47 on Sep 20, 2018

Ape Fist
Feb 23, 2007

Nowadays, you can do anything that you want; anal, oral, fisting, but you need to be wearing gloves, condoms, protection.
We're working in ASP.NET MVC5 with a layer on top of it called Episerver, a gigantic retail CMS system with a bunch of very complex and very intelligent systems which requires MVC5 to be configured a specific way.

We're rebuilding a generic template and myself and another developer have been assigned to redo the front-end to our liking.

We want to build it with a component-centric focus in a method similar to a modern front-end framework, but we're not going to be using a front-end framework just yet because we want to have the freedom to bolt on angular or react later on down the line. For now we're just going to start off with accompanying ES6 files which we transpile to ES5 via webpack alongside the CHTML block files.

The problem:

We cannot have control of the DOM, we can't return the DOM through a JS file because our .NET requires control of the views on the back-end however we still want to try and implement some sort of basic contemplating engine on top of what we're doing so at least when the DOM is rendered from the back we have SOME dynamic control of whats going on. We're explicitly trying to move away from jQuery.

Any ideas?

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!

Hypnobeard posted:

Thinking about it, my question is more "how do I get the error in an Array?"--because the ways I know about don't seem to produce what the test is looking for.
I don't think the square brackets in the test output signify that it wanted the error to be thrown in the form of an array. It looks more like it was just trying to be clear about where the ends of the string are.
(Especially since you showed the test code and it wasn't saying expect it to throw an array.)
It is a bit poo poo of the framework not to use the same delimeters for the "what you got" output though.

Adbot
ADBOT LOVES YOU

playground tough
Oct 29, 2007
At work I inherited a truly piece of poo poo backend. It's a node.js project that utilizes parse-server for practically everything. The previous devs were too inept to properly segment code in a way that it can be separated from the parse library without an insane amount of dev team commitment and acceptance of a rewrite by management.

My best effort to tame this and to confidently make changes to the code base has been to implement tests, however, the code is so poo poo that you cannot unit test preexisting code without crazy commitment to refactoring and calculated breaking of dependencies. Because of this the best I have been able to do is implement black box testing wherever I can.

This is shaping up to not be enough test depth to confidently add features and iterate quickly. Am I insane/dumb for thinking it may be a good idea to establish a communication line between the server instance running locally in a test environment to our actual test process using something like socket io? Would be used to send messages indicating the state of the "black box" internals using a module thats executed via one-liners. It would add lines of code but nothing that wouldn't be self documenting or able to be cleaned out easily. It would not affect production environment, and I would really like to have the ability to run deeper tests on this pos.

We also looked at the potential of monitoring outgoing communications via a mitm proxy and, again, using some sort of connection between test env and test process to determine whether the server was firing requests when it should/shouldn't be. Problem with that is it is more limited versus the messaging system I am thinking of implementing.

Any thoughts or alternative suggestions? Cannot afford a rewrite - wish I could.

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