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
Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.
I've got some middle school students working on turtle drawing in a web based JS/Typescript environment that I set up. One of the tasks that I set them to begin with was to make functions to draw letters, so now I've got a bunch of functions a(size, x, y), b(size, x, y), c(size, x, y), etc.

Any suggestions on how best to make a function now that takes a string and uses the letter functions to draw it? The first thing I thought to do is a big ol switch statement or if/else chain to call different functions based on the characters in the string. Could also use the input string to generate code that gets eval'd (this isn't exactly a high-security environment). Also could toss all of the drawing functions into an object and reference them through that:

JavaScript code:
letterFunctions = {
  a: function(size, x, y) { ... }
  A: function(size, x, y) { ... }
  ...
}

drawString(text: string, size: number, x: number, y: number){
	// loop stuff
	letterFunctions[text.charAt(i)](size, incrementedX, y)
}
Any of these stand out as less awful / better as a teaching tool?

Adbot
ADBOT LOVES YOU

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

Newf posted:

I've got some middle school students working on turtle drawing in a web based JS/Typescript environment that I set up. One of the tasks that I set them to begin with was to make functions to draw letters, so now I've got a bunch of functions a(size, x, y), b(size, x, y), c(size, x, y), etc.

Any suggestions on how best to make a function now that takes a string and uses the letter functions to draw it? The first thing I thought to do is a big ol switch statement or if/else chain to call different functions based on the characters in the string. Could also use the input string to generate code that gets eval'd (this isn't exactly a high-security environment). Also could toss all of the drawing functions into an object and reference them through that:

JavaScript code:
letterFunctions = {
  a: function(size, x, y) { ... }
  A: function(size, x, y) { ... }
  ...
}

drawString(text: string, size: number, x: number, y: number){
	// loop stuff
	letterFunctions[text.charAt(i)](size, incrementedX, y)
}
Any of these stand out as less awful / better as a teaching tool?

I would go with the hash-table version. Much easier to extend if you add new letters/symbols. I would leave the functions defined elsewhere, and just have the letterFunctions hashtable point to them.

Happy Thread
Jul 10, 2005

by Fluffdaddy
Plaster Town Cop
Definitely like that hash table / JavaScript object version over a big inflexible switch statement

Newf
Feb 14, 2006
I appreciate hacky sack on a much deeper level than you.

Skandranon posted:

I would go with the hash-table version. Much easier to extend if you add new letters/symbols. I would leave the functions defined elsewhere, and just have the letterFunctions hashtable point to them.

OK, gonna do this.

Will have to move all of the Fcns to one file though because of the nature of the dev environment that I've got set up. It's a real Frankenstein already. Enabling imports etc isn't in the cards for the time being.

ROFLburger
Jan 12, 2006

Just kind of wondering out loud - why hasn't there been some kind of spec for more rigid number types like a Big Decimal or something like that? Having to work around floating/double arithmetic seems like a pretty common problem that might be easy to mitigate with a new type?

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

ROFLburger posted:

Just kind of wondering out loud - why hasn't there been some kind of spec for more rigid number types like a Big Decimal or something like that? Having to work around floating/double arithmetic seems like a pretty common problem that might be easy to mitigate with a new type?

I most people that really care about this just use a language with good Big Decimal support.

MrMoo
Sep 14, 2000

You could probably just use WebAssembly now and dump to a JS string.

Roadie
Jun 30, 2013

Newf posted:

I've got some middle school students working on turtle drawing in a web based JS/Typescript environment that I set up. One of the tasks that I set them to begin with was to make functions to draw letters, so now I've got a bunch of functions a(size, x, y), b(size, x, y), c(size, x, y), etc.

Any suggestions on how best to make a function now that takes a string and uses the letter functions to draw it? The first thing I thought to do is a big ol switch statement or if/else chain to call different functions based on the characters in the string. Could also use the input string to generate code that gets eval'd (this isn't exactly a high-security environment). Also could toss all of the drawing functions into an object and reference them through that:

JavaScript code:
letterFunctions = {
  a: function(size, x, y) { ... }
  A: function(size, x, y) { ... }
  ...
}

drawString(text: string, size: number, x: number, y: number){
	// loop stuff
	letterFunctions[text.charAt(i)](size, incrementedX, y)
}
Any of these stand out as less awful / better as a teaching tool?

Personally, I'd have it be a function rather than the hash table directly that gets used for the lookup, and have it also serve as a real simple introduction to composability of functions.

For example:

JavaScript code:
const letterFunctions = {
  a: function(size: number, x: number, y: number) {
    //...
  }
  A: function(size: number, x: number, y: number) {
    // ...
  }
  // ...
}

function drawLetter(letter: string) {
  return letterFunctions[letter]
    ? letterFunctions[letter]
    : function () { return }
}

function drawString(text: string, size: number, x: number, y: number) {
  // loop stuff
  drawLetter(text.charAt(i))(size, incrementedX, y)
}
(Or embed the hash table in the function as a switch statement, if you want to get the kids ready for playing with reducers. :v:)

Roadie fucked around with this message at 20:27 on Nov 14, 2017

porksmash
Sep 30, 2008
I'm having what is probably a Javascript/redux noob issue, but is driving me crazy. The issue is with ES6 imports not being able to resolve a specific module that I have put my reducers into. Here's the relevant code: https://github.com/PeteAndersen/swarfarm-fe/blob/master/src/state/store.js. The error I'm encountering is that redux complains that no reducer provided for key 'auth'. If I console.log(reducers.auth) in state.js it is indeed undefined. But the other two keys, bestiary and news work fine.

What gets me confused is that import * as reducers from 'state/ducks' in my root index.js file successfully imports all 3 reducer functions as expected and fully resolved, so it is something specific about store.js that is causing issues resolving just the one module. I'd greatly appreciate any insight into why this is happening.

Dogcow
Jun 21, 2005

porksmash posted:

I'm having what is probably a Javascript/redux noob issue, but is driving me crazy. The issue is with ES6 imports not being able to resolve a specific module that I have put my reducers into. Here's the relevant code: https://github.com/PeteAndersen/swarfarm-fe/blob/master/src/state/store.js. The error I'm encountering is that redux complains that no reducer provided for key 'auth'. If I console.log(reducers.auth) in state.js it is indeed undefined. But the other two keys, bestiary and news work fine.

What gets me confused is that import * as reducers from 'state/ducks' in my root index.js file successfully imports all 3 reducer functions as expected and fully resolved, so it is something specific about store.js that is causing issues resolving just the one module. I'd greatly appreciate any insight into why this is happening.

The only thing I see is that in the other reducers.js you’re exporting the reducer directly with “export default function()” whereas in the auth reducers you’re defining the reducer as a named constant and then exporting as the default. I believe either should work but it’s the only difference I see so maybe try changing that to match the others.

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself
quick React question that I may already know the answer to:

Here's the problem: When my component is mounted, I am making a fetch request to a server to get a list of posts. But when I refresh the page 'domain.com/post/post123', I get a 404 page, which should only happen if the post does not exist in my global state. This shouldn't be happening because the post123 exists, but the initial render happens before the fetch request is done.

I was thinking of having a local state called 'is404Showing: false' and then set it to true is the fetch request finishes and the post doesn't exist. The only problem here is that the page load would take longer than I'd like. Am I going about this all wrong?

My thought is that doing this client-side is just not possible

teen phone cutie fucked around with this message at 22:41 on Nov 14, 2017

porksmash
Sep 30, 2008

Dogcow posted:

The only thing I see is that in the other reducers.js you’re exporting the reducer directly with “export default function()” whereas in the auth reducers you’re defining the reducer as a named constant and then exporting as the default. I believe either should work but it’s the only difference I see so maybe try changing that to match the others.

Oops, that was actually me trying something different to see if it would work. Originally it was the same as others w/ "export default function()". In either case it fails the same way :(

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

porksmash posted:

I'm having what is probably a Javascript/redux noob issue, but is driving me crazy. The issue is with ES6 imports not being able to resolve a specific module that I have put my reducers into. Here's the relevant code: https://github.com/PeteAndersen/swarfarm-fe/blob/master/src/state/store.js. The error I'm encountering is that redux complains that no reducer provided for key 'auth'. If I console.log(reducers.auth) in state.js it is indeed undefined. But the other two keys, bestiary and news work fine.

What gets me confused is that import * as reducers from 'state/ducks' in my root index.js file successfully imports all 3 reducer functions as expected and fully resolved, so it is something specific about store.js that is causing issues resolving just the one module. I'd greatly appreciate any insight into why this is happening.

That should be working. This is pretty much the exact thing I do all the time and it's working just fine:

JavaScript code:
// /redux/index.js
export { default as auth } from './auth';
export { default as page } from './page';
export { default as profile } from './profile';
...


//configureStore.js
import * as reducers from './redux';
const rootReducer = combineReducers({ ...reducers, location: routerReducer })
const store = createStore( rootReducer, initialState, enhancers );

Joda
Apr 24, 2010

When I'm off, I just like to really let go and have fun, y'know?

Fun Shoe

MrMoo posted:

You could probably just use WebAssembly now and dump to a JS string.

WebAssembly still suffers a lot from lacking introduction and learning material and immature tooling (even compiling that one basic tutorial I managed to find with emscripten was a pain in the rear end, and didn't really teach me anything of value.) With what little I've dabbled in it, I wouldn't recommend diving into it for anything other than a direct interest in WebAssembly and its possibilities, and definitely not just to get big decimals.

I'd at the very least wait with using WebAssembly beyond basic research until some more mature tools come around (like at the very least GNU, MS or the Clang guys providing a full toolchain or something.)

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Grump posted:

quick React question that I may already know the answer to:

Here's the problem: When my component is mounted, I am making a fetch request to a server to get a list of posts. But when I refresh the page 'domain.com/post/post123', I get a 404 page, which should only happen if the post does not exist in my global state. This shouldn't be happening because the post123 exists, but the initial render happens before the fetch request is done.

I was thinking of having a local state called 'is404Showing: false' and then set it to true is the fetch request finishes and the post doesn't exist. The only problem here is that the page load would take longer than I'd like. Am I going about this all wrong?

My thought is that doing this client-side is just not possible

I generally have an `isFetching` flag when I am doing requests so I can render a loading animation. The actions that handle receiving the data or handling an error set it to false.

porksmash
Sep 30, 2008

porksmash posted:

I'm having what is probably a Javascript/redux noob issue, but is driving me crazy. The issue is with ES6 imports not being able to resolve a specific module that I have put my reducers into. Here's the relevant code: https://github.com/PeteAndersen/swarfarm-fe/blob/master/src/state/store.js. The error I'm encountering is that redux complains that no reducer provided for key 'auth'. If I console.log(reducers.auth) in state.js it is indeed undefined. But the other two keys, bestiary and news work fine.

What gets me confused is that import * as reducers from 'state/ducks' in my root index.js file successfully imports all 3 reducer functions as expected and fully resolved, so it is something specific about store.js that is causing issues resolving just the one module. I'd greatly appreciate any insight into why this is happening.

Finally resolved this by discovering a circular import issue in my auth state sagas. Here's the problem lines: https://github.com/PeteAndersen/swarfarm-fe/commit/3142e35a77596d4341d4a14ffcc56c4198d3d0c0

history is imported from state.js, state.js imports from auth/ module... guess it confused things.

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself
I just learned how to unit test today and am realizing how brain dead easy it is

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Grump posted:

I just learned how to unit test today and am realizing how brain dead easy it is

Now comes the hard part: writing tests when your brain / boss is saying "You don't have time!" or "You can add them later!!"

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself
I went to this conference today which was explaining Jest and test-driven development.

We were basically making a program that would print out the name of a number (i.e. 55 returns fifty-five). The way they explained it was to write your test and then write barely enough code to have the test pass and if need be, refactor later. Which was getting obnoxious after the 5th time I had to refactor, but it was an interesting approach.

I had always shrugged off testing just because I never really found a good tutorial on it and most test runners I've seen have really bad docs. But gently caress is it simple.

lunar detritus
May 6, 2009


Grump posted:

I went to this conference today which was explaining Jest and test-driven development.

We were basically making a program that would print out the name of a number (i.e. 55 returns fifty-five). The way they explained it was to write your test and then write barely enough code to have the test pass and if need be, refactor later. Which was getting obnoxious after the 5th time I had to refactor, but it was an interesting approach.

I had always shrugged off testing just because I never really found a good tutorial on it and most test runners I've seen have really bad docs. But gently caress is it simple.

It's extremely simple until you need to mock things, then it can turn into a tedious nightmare.

I still haven't found a good way to get tests going with Ionic (Angular 5) + ngrx that doesn't end up breaking. They have been promising testing support in their cli since the launch of Ionic 2 almost a year ago :negative:.

camoseven
Dec 30, 2005

RODOLPHONE RINGIN'
I’ve done a few TDD trainings and always come away thinking “wow that was cool, but there’s no way it scales well or works well with async calls”. I would love to be proven wrong, though.

I’ve never done a training that used JS, so maybe that’s part of the issue.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

camoseven posted:

I’ve done a few TDD trainings and always come away thinking “wow that was cool, but there’s no way it scales well or works well with async calls”. I would love to be proven wrong, though.

I’ve never done a training that used JS, so maybe that’s part of the issue.

Mocking stuff can be a headache, but once you spend the time doing it once, it's not that bad. Here's a test for my `auth` actions / reducers, which involve an async call. I use `nock` to mock out all HTTP calls, and `redux-mock-store` to give me a temporary store to collect actions:

JavaScript code:
import configureMockStore from 'redux-mock-store'
import nock from 'nock'
import thunk from 'redux-thunk'

const validLoginReturn = {"hooray": "you did it"};
const mockHeaders = {
    'Content-type': 'application/json',
}

describe('successful requests', () => {
    beforeEach( () => {
        let goodLogin = nock( api_url )
        .post('/auth/token')
        .reply( 200, validLoginReturn, mockHeaders )
    });

    afterEach(() => {
        nock.cleanAll();
    });

    it('says we are authing then handles success on good login', () => {
        const expectedActions = [
            { type: actions.AUTH_ACTIONS.REQUESTING_AUTHENTICATION },
            { type: actions.AUTH_ACTIONS.AUTHENTICATION_SUCCESS, data: validLoginReturn },
            { type: ROUTE_ACTIONS.HOME },
        ];
        const store = mockStore({ 
            authenticated: false,
            requestingAuthentication: false,
        });
        return store.dispatch(actions.auth( 'a@b.com', 'a' )).then(() => {
            expect(store.getActions()).toEqual(expectedActions)
        })
    });
});

It's a little verbose, but it tests the whole successful login workflow in one go.

ArcticZombie
Sep 15, 2010
With synchronous XHR being deprecated, is there a go to method if a request absolutely must be synchronous? Other than don't do it. For a university project, I'm creating an extension which absolutely must make a request and receive a response before headers are sent to the web server, user experience be damned.

necrotic
Aug 2, 2005
I owe my brother big time for this!
Extension for what? Just move everything "after" the XHR call to the success/failure chain. There's no way to make something async not async.

ArcticZombie
Sep 15, 2010
I'm comparing certificate information for a web server over different routes, as part of detecting some kind of man-in-the-middle (benevolent or malicious). Ideally, the detection should finish before any further information (headers for example) are sent over the potentially poisoned route. Using Firefox's WebExtension API, I can listen for onBeforeRequest events and I can return either an object with properties for cancelling/redirecting the request or a promise which is resolved with such an object. However, I need to block while I wait for a response from the alternative routes in order to carry out the comparison before any headers are sent.

If it's not possible I could maybe immediately redirect to some kind of intermediate "checking" page or something.

ArcticZombie fucked around with this message at 01:23 on Nov 18, 2017

MrMoo
Sep 14, 2000

ArcticZombie posted:

With synchronous XHR being deprecated, is there a go to method if a request absolutely must be synchronous?
Try the Fetch API?
code:
let response = await fetch("http://💩.com")

ArcticZombie
Sep 15, 2010
That seems to work as expected. In fact, I wasn't aware await and asynchronous functions existed, with them I can use websockets as I originally planned along with promises.

Happy Thread
Jul 10, 2005

by Fluffdaddy
Plaster Town Cop
If you go to that URL he provided you'll find that it's pretty lovely

MrMoo
Sep 14, 2000

:golfclap:

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

ArcticZombie posted:

That seems to work as expected. In fact, I wasn't aware await and asynchronous functions existed, with them I can use websockets as I originally planned along with promises.

Await doesn't actually make something synchronous, it basically just wraps around promises and makes your code LOOK like it's synchronous, but it still is actually async. Sync would imply you hold up all rendering and JS evaluation until your request comes back, and you really never want to do this.

ArcticZombie
Sep 15, 2010
I'm familiar with the concept from Python's asyncio. If it works anything like that then I understand that the function releases control yada yada, but it does the job I required of blocking the request until the function actually returns a value.

Roadie
Jun 30, 2013

ArcticZombie posted:

I'm familiar with the concept from Python's asyncio. If it works anything like that then I understand that the function releases control yada yada, but it does the job I required of blocking the request until the function actually returns a value.

One thing to watch out for: if you await and the promise rejects, the line you have doing the await will throw an exception. If you set it up right this can bubble through fine, as a function with await in it will itself return a promise of the return value rather than the return value itself and will turn any thrown exceptions into a rejected promise with the error, but this can mess with you if you don't plan for it.

Basically, these are the same thing:
JavaScript code:
function dalek () {
  return Promise.reject(new Error('EXTERMINATE! EXTERMINATE!'))
}

function doctor () {
  return dalek().catch(err => console.log('Not today!'))
}
JavaScript code:
async function dalek () {
  throw new Error('EXTERMINATE! EXTERMINATE!')
}

async function doctor () {
  try {
    return await dalek()
  } catch (err) {
    return console.log('Not today!')
  }
}
...and, barring any fuckups from me doing this off the top of my head, both versions of both functions are totally interchangeable.

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.
Can anyone explain to me what getters, setters and static class methods are in es6? I simply don't get what makes them different or what their purpose is. Something like this:

code:
class Languages {
    static get LabelsById() {
        return {
             0: 'English',
             1: 'Spanish'
        };
     }
}

Roadie
Jun 30, 2013

Knifegrab posted:

Can anyone explain to me what getters, setters and static class methods are in es6? I simply don't get what makes them different or what their purpose is. Something like this:

code:
class Languages {
    static get LabelsById() {
        return {
             0: 'English',
             1: 'Spanish'
        };
     }
}

Compare the following:

JavaScript code:
class Dalek {
  _catchprase = 'EXTERMINATE!'

  getCatchphrase () {
    return this._catchprase
  }

  setCatchphrase (val) {
    this._catchphrase = val
  }
}

const dalek = new Dalek()
console.log(dalek.getCatchphrase())

dalek.setCatchphrase('LEVITATE!')
console.log(dalek.getCatchphrase())
JavaScript code:
class Dalek {
  _catchprase = 'EXTERMINATE!'

  get catchphrase () {
    return this._catchprase
  }

  set catchphrase (val) {
    this._catchphrase = val
  }
}

const dalek = new Dalek()
console.log(dalek.catchphrase)

dalek.catchphrase = 'LEVITATE!'
console.log(dalek.catchphrase)

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Knifegrab posted:

Can anyone explain to me what getters, setters and static class methods are in es6? I simply don't get what makes them different or what their purpose is. Something like this:

code:
class Languages {
    static get LabelsById() {
        return {
             0: 'English',
             1: 'Spanish'
        };
     }
}

set and get override property assignment, letting you mess with it if need be.


Static methods are attached to the class, not on instances of the class. For example, Math.min() is effectively a static function. You don't need to make a Math, then use it.

Happy Thread
Jul 10, 2005

by Fluffdaddy
Plaster Town Cop
I never looked into using getters and setters, but does that mean that code like this isn't what they're intended for?

code:
class Languages {
    static get LabelsById() {
        return {
             0: 'English',
             1: 'Spanish'
        };
     }
}

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.

Roadie posted:

Compare the following:

JavaScript code:
class Dalek {
  _catchprase = 'EXTERMINATE!'

  getCatchphrase () {
    return this._catchprase
  }

  setCatchphrase (val) {
    this._catchphrase = val
  }
}

const dalek = new Dalek()
console.log(dalek.getCatchphrase())

dalek.setCatchphrase('LEVITATE!')
console.log(dalek.getCatchphrase())
JavaScript code:
class Dalek {
  _catchprase = 'EXTERMINATE!'

  get catchphrase () {
    return this._catchprase
  }

  set catchphrase (val) {
    this._catchphrase = val
  }
}

const dalek = new Dalek()
console.log(dalek.catchphrase)

dalek.catchphrase = 'LEVITATE!'
console.log(dalek.catchphrase)

So when you make an assignment instead of actually assigning it, it passed the value through the function? I suppose I understand the mechanism but I just don't get the point?

Knifegrab fucked around with this message at 08:19 on Nov 22, 2017

ElCondemn
Aug 7, 2005


Dumb Lowtax posted:

I never looked into using getters and setters, but does that mean that code like this isn't what they're intended for?

code:
class Languages {
    static get LabelsById() {
        return {
             0: 'English',
             1: 'Spanish'
        };
     }
}

There is no reason to use a getter here. In most cases you can just set properties of an object without adding custom setters or getters. Like so:

code:
class Languages {
}

var obj = new Languages();
obj.labels = {
  0: 'English',
  1: 'Spanish'
}

obj.labels // returns your labels
Here's a nice rundown of what they're for and how to use them, I would avoid using them unless you have a good reason to though.

https://javascriptplayground.com/blog/2013/12/es5-getters-setters/

ElCondemn fucked around with this message at 08:53 on Nov 22, 2017

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

The big advantage of getters and setters is updating you code without changing its API.

Adbot
ADBOT LOVES YOU

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Knifegrab posted:

So when you make an assignment instead of actually assigning it, it passed the value through the function? I suppose I understand the mechanism but I just don't get the point?

Exactly. The point is to help you avoid possible mistakes / bad app states. Here's a totally contrived example!

JavaScript code:
class Divide {
   constructor () {
      this.denominator = 1;
      this.numerator = 10;
   }
   set denominator ( val ) {
       if (val !== 0) {
          this.denominator = val;
       }
   }
   result() {
       return this.numerator/this.denominator;
   }
}
Now instances of this class can't have divide by zero errors, since if you try and set the denominator to zero, it won't.

A getter example would be a class that when you access a string property translates it into another language for you based on a setting / property in the class.

EDIT: And that class could have a setter method for the language that checks to see if you set it to an allowed language, and if not, it defaults to english or whatever.

Lumpy fucked around with this message at 16:47 on Nov 22, 2017

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