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
Roadie
Jun 30, 2013
Use redux, do your request stuff in redux action creators via redux-pack, use reselect to bind your child components to the specific bits of the redux store being used.

Adbot
ADBOT LOVES YOU

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself
Welp just learned about fetch.

Holy crap

necrotic
Aug 2, 2005
I owe my brother big time for this!
Yeah fetch is awesome. It has one glaring flaw, however: requests cannot be cancelled! This isn't necessary in a lot of situations, but does mean falling back to an XHR wrapper with cancellation if you need it.

Dominoes
Sep 20, 2007

Nicer than using JQuery's AJAX, but wish there was a way to circumvent the async syntax associated with it and the related json() func.

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

Dominoes posted:

Nicer than using JQuery's AJAX, but wish there was a way to circumvent the async syntax associated with it and the related json() func.

You can use it in a purely Promise based way, and you can always just use text().then( (text) => { return JSON.parse(text); }) to handle the parsing yourself.

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself
The tutorial I was watching said that the great thing about fetch was that it returned a promise.

But that's the same for JQuery and XHR requests correct?

teen phone cutie fucked around with this message at 18:11 on Sep 5, 2017

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

Grump posted:

The tutorial I was watching said that the great thing about fetch was that it returned a promise.

But that's try for JQuery and XHR requests correct?

I guess? Promises are just a better way to manage callbacks.

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself
I meant 'the same' instead of 'try' LOL that sentence didn't make any sense

Bob Morales
Aug 18, 2006


Just wear the fucking mask, Bob

I don't care how many people I probably infected with COVID-19 while refusing to wear a mask, my comfort is far more important than the health and safety of everyone around me!

What's a good way to test if a string contains any of a list of strings?

if (foobar.indexOf('CNN') >= 0) {
doSomething
} else if (foobar.indexOf('MSNBC') >= 0) {
doSomething
} else if(foobar.indexOf('ABCNEWS') >= 0 {
doSomething
} else if(foobar.indexOf('FOXNEWS') >= 0 {
doSomeOtherThing
}

Does something like ifStringContains(foobar, 'CNN', 'MSNBC', 'FOXNEWS') exist or should I write my own?

Roadie
Jun 30, 2013
Simple, lovely monkey-patch version:

code:
String.prototype.containsOne = function (strs) {
  if (!(strs instanceof Array)) {
    return false
  }

  var matches = false
  strs.forEach(function (str) {
    if (this.indexOf(str) !== -1) {
      matches = true
    }
  })

  return matches
}

if (foobar.containsOne(['string1', 'string2', 'string3'])) {
  whatever()
}

geeves
Sep 16, 2004

Bob Morales posted:

What's a good way to test if a string contains any of a list of strings?

if (foobar.indexOf('CNN') >= 0) {
doSomething
} else if (foobar.indexOf('MSNBC') >= 0) {
doSomething
} else if(foobar.indexOf('ABCNEWS') >= 0 {
doSomething
} else if(foobar.indexOf('FOXNEWS') >= 0 {
doSomeOtherThing
}

Does something like ifStringContains(foobar, 'CNN', 'MSNBC', 'FOXNEWS') exist or should I write my own?

String.includes is part of the standard. Just not supported by previous browsers.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes

We use this and the polyfill for IE11 in production. We don't support previous to that, so I can't speak to what works.

Edit: I hate to say RTFM, but I did this summer on a project that had me doing some things with JavaScript that needed to be in VanillaJS and I basically refreshed myself on how rich JS actually is in its API. MDN has really be an invaluable resource.

geeves fucked around with this message at 22:12 on Sep 1, 2017

obstipator
Nov 8, 2009

by FactsAreUseless
i think doing a regex test would be the cleanest

/(CNN|MSNBC)/i.test(thing)

and if you just want to make a list of strings, you could pass it thru a regex escape func and merge them into a neato regex.

ROFLburger
Jan 12, 2006

geeves posted:

String.includes is part of the standard. Just not supported by previous browsers.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes

We use this and the polyfill for IE11 in production. We don't support previous to that, so I can't speak to what works.

Edit: I hate to say RTFM, but I did this summer on a project that had me doing some things with JavaScript that needed to be in VanillaJS and I basically refreshed myself on how rich JS actually is in its API. MDN has really be an invaluable resource.

I don't think he's looking for an alternative to indexOf

Doom Mathematic
Sep 2, 2008

Bob Morales posted:

What's a good way to test if a string contains any of a list of strings?

if (foobar.indexOf('CNN') >= 0) {
doSomething
} else if (foobar.indexOf('MSNBC') >= 0) {
doSomething
} else if(foobar.indexOf('ABCNEWS') >= 0 {
doSomething
} else if(foobar.indexOf('FOXNEWS') >= 0 {
doSomeOtherThing
}

Does something like ifStringContains(foobar, 'CNN', 'MSNBC', 'FOXNEWS') exist or should I write my own?

JavaScript code:
if (['CNN', 'MSNBC', 'ABCNEWS'].some(x => foobar.indexOf(x) !== -1)) {
  doSomething()
}

necrotic
Aug 2, 2005
I owe my brother big time for this!

Grump posted:

The tutorial I was watching said that the great thing about fetch was that it returned a promise.

But that's try for JQuery and XHR requests correct?

e: I mean that's the same for JQuery and XHR?

XHR does not return a promise, it uses events. jQuery returns a jQuery.deferred object (or did last time I looked which was forever ago).

Sedro
Dec 31, 2008

necrotic posted:

XHR does not return a promise, it uses events. jQuery returns a jQuery.deferred object (or did last time I looked which was forever ago).

Deferred is a "thenable", similar to Promise but with different APIs and runtime semantics (worse in every way). It's easy to convert to a real promise with Promise.resolve() or by just using async/await.

Dominoes
Sep 20, 2007

Hey dudes, looking for wisdom on moving from Jquery AJAX requests to fetch. Here's what I've got: Get works OK, but my Django server is getting empty post data:

JavaScript code:
fetch("/inputs/", {
                            method: 'POST',
                            headers: {
                                "X-CSRFToken": getCookie('csrftoken'),  // Need this to prevent a permission error from server
                            "Content-Type": "application/json",  // Do I need this?
                            "Accept": "application/json",  // Do I need this?
                            "X-Requested-With": "XMLHttpRequest"  // Saw this online troubleshooting
                            },
                            credentials: 'include',  // Need this to prevent a permission error from server
                            // body: JSON.stringify({type: 'export'})  // POST data; server is getting an empty dict.  Do I stringify or send a raw dict?
                            body: {type: 'export'}
                        })
                            .then(result => result.json())  // Async process return data
                            .then(data => console.log("done"))  // Async parse return JSON in JS object
                    }
Once sorted, I'm going to release a simple package with a cleanern API so you can just do something like:

JavaScript code:
quickFetch.post(url, data)

Dominoes fucked around with this message at 19:15 on Sep 4, 2017

Dogcow
Jun 21, 2005

JavaScript code:

fetch("/inputs/", {
                            method: 'POST',
                            headers: {
                                "X-CSRFToken": getCookie('csrftoken'),  // Need this to prevent a permission error from server
                            "Content-Type": "application/json",  // Do I need this?
                            "Accept": "application/json",  // Do I need this?
                            "X-Requested-With": "XMLHttpRequest"  // Saw this online troubleshooting
                            },
                            credentials: 'include',  // Need this to prevent a permission error from server
                            // body: JSON.stringify({type: 'export'})  // POST data; server is getting an empty dict.  Do I stringify or send a raw dict?
                            body: {type: 'export'}
                        })
                            

JSON.stringify should be right, can you verify/post the actual request made by the browser?

Dominoes
Sep 20, 2007

How do I do that? I looked it up/clicked F12/Network in chrome, then clicked the request; it showed me a big server-side log.

Dogcow
Jun 21, 2005

Dominoes posted:

How do I do that? I looked it up/clicked F12/Network in chrome, then clicked the request; it showed me a big server-side log.

You're on either the preview or response tabs and that's an error log from your server so it should probably have something in there about why it's blowing up.



Click the Headers tab and then look under Request Payload at the bottom right, it should have your post object ({type: 'export'}).

Thermopyle
Jul 1, 2003

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

Dominoes posted:

Hey dudes, looking for wisdom on moving from Jquery AJAX requests to fetch. Here's what I've got: Get works OK, but my Django server is getting empty post data:

JavaScript code:
fetch("/inputs/", {
                            method: 'POST',
                            headers: {
                                "X-CSRFToken": getCookie('csrftoken'),  // Need this to prevent a permission error from server
                            "Content-Type": "application/json",  // Do I need this?
                            "Accept": "application/json",  // Do I need this?
                            "X-Requested-With": "XMLHttpRequest"  // Saw this online troubleshooting
                            },
                            credentials: 'include',  // Need this to prevent a permission error from server
                            // body: JSON.stringify({type: 'export'})  // POST data; server is getting an empty dict.  Do I stringify or send a raw dict?
                            body: {type: 'export'}
                        })
                            .then(result => result.json())  // Async process return data
                            .then(data => console.log("done"))  // Async parse return JSON in JS object
                    }
Once sorted, I'm going to release a simple package with a cleanern API so you can just do something like:

JavaScript code:
quickFetch.post(url, data)

I don't think there's a need for a simpler package. One of the problems with npm is that 90% of the packages are like 10 lines of code.

Fetch is basically exactly as complicated as it needs to be to cover the common use cases. In your application, you select out the parts of the fetch API you need and wrap them in a 5 line function.

Dominoes
Sep 20, 2007

Dogcow posted:

You're on either the preview or response tabs and that's an error log from your server so it should probably have something in there about why it's blowing up.


Click the Headers tab and then look under Request Payload at the bottom right, it should have your post object ({type: 'export'}).
Thanks. Looks right - maybe I have a server-side bug?
code:
{type: "export"}
type
:
"export"

Thermopyle posted:

I don't think there's a need for a simpler package. One of the problems with npm is that 90% of the packages are like 10 lines of code.

Fetch is basically exactly as complicated as it needs to be to cover the common use cases. In your application, you select out the parts of the fetch API you need and wrap them in a 5 line function.
Sounds like an indication of a sparse standard library / verbose APIs. I already consider Lodash effectively part of JS.

Compare the fetch api to Requests.

Thermopyle
Jul 1, 2003

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

Dominoes posted:

Sounds like an indication of a sparse standard library / verbose APIs.

This is exactly right and the current NPM situation is a terrible solution to that problem.





Dominoes posted:

Compare the fetch api to Requests.

The fetch api is pretty elegant compared to what requests is hiding.

It doesn't hide as much details as Requests, but it's also trivial to wrap the fetch API. Requests does a ton of work to make it as easy to use as it is.

Also, there's already (as per what you'd expect with NPM and the JS ecosystem), well over a 100 fetch wrappers out there...and a brief perusal of a few of them show them to be extremely minimal thingamabobs. (see above xkcd for the problem with this)

I mean, I don't think there's anything exactly wrong with writing the 200th fetch wrapper, but I question its usefulness.

Dominoes posted:

I already consider Lodash effectively part of JS.

https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore

lunar detritus
May 6, 2009



I got bitten by this today because I'm so used to typescript that I used Object.values in a normal javascript project months ago and today somebody discovered that it didn't work in older iphones. :v:

Ranzear
Jul 25, 2013

http://vanilla-js.com/

Dominoes
Sep 20, 2007

Thermopyle posted:

The fetch api is pretty elegant compared to what requests is hiding.

It doesn't hide as much details as Requests, but it's also trivial to wrap the fetch API. Requests does a ton of work to make it as easy to use as it is.
That's the point of a high-level API, and what I'm looking for.

quote:

Also, there's already (as per what you'd expect with NPM and the JS ecosystem), well over a 100 fetch wrappers out there...and a brief perusal of a few of them show them to be extremely minimal thingamabobs. (see above xkcd for the problem with this)
Have you Ided any particularly good ones? You're right that writing a fetch wrapper at the top of each script is easy, and the fetch api isn't that bad, if you know what the boilerplate/headers are supposed to look like.

Nice! Going to ref that each time I try to use a Lodash func.

Dominoes fucked around with this message at 02:54 on Sep 5, 2017

The Fool
Oct 16, 2003


Just make your fetch wrapper an npm module with fetch as a dependency. Then you just need to install and include it when you want to use it.



dont do this

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

Dominoes posted:


Once sorted, I'm going to release a simple package with a cleanern API so you can just do something like:

JavaScript code:
quickFetch.post(url, data)

If you just want to auto-serialize and use the same headers, just write a function that does that. Don't try to make a package out of it. You can take DRY too far.

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 really would not like to give up lodash's matcher shorthands. They're super nice once you're used to them, especially the matchesProperty ones.

code:
var users = [
  { 'user': 'barney',  'age': 36, 'active': true },
  { 'user': 'fred',    'age': 40, 'active': false },
  { 'user': 'pebbles', 'age': 1,  'active': true }
];
 
_.find(users, function(o) { return o.age < 40; });
// => object for 'barney'
 
// The `_.matches` iteratee shorthand.
_.find(users, { 'age': 1, 'active': true });
// => object for 'pebbles'
 
// The `_.matchesProperty` iteratee shorthand.
_.find(users, ['active', false]);
// => object for 'fred'

Dogcow
Jun 21, 2005

Osmosisch posted:

I really would not like to give up lodash's matcher shorthands. They're super nice once you're used to them, especially the matchesProperty ones.

code:
var users = [
  { 'user': 'barney',  'age': 36, 'active': true },
  { 'user': 'fred',    'age': 40, 'active': false },
  { 'user': 'pebbles', 'age': 1,  'active': true }
];
 
_.find(users, function(o) { return o.age < 40; });
// => object for 'barney'
 
// The `_.matches` iteratee shorthand.
_.find(users, { 'age': 1, 'active': true });
// => object for 'pebbles'
 
// The `_.matchesProperty` iteratee shorthand.
_.find(users, ['active', false]);
// => object for 'fred'

But.. if you use ES6 syntax the native array filter method is actually shorter in most of your examples :confused:

JavaScript code:
users.filter(u => u.age < 40);
And you can use object destructuring to reduce boiler plate further if you want:

JavaScript code:
users.filter(({age, active}) => active && age === 1);
Plus it's native so it's going to be the fastest implementation unless the browser is complete garbage somehow.

Dominoes
Sep 20, 2007

-delete

Dominoes
Sep 20, 2007

Dogcow posted:

You're on either the preview or response tabs and that's an error log from your server so it should probably have something in there about why it's blowing up.



Click the Headers tab and then look under Request Payload at the bottom right, it should have your post object ({type: 'export'}).


Working Jquery post on the left; empty-data Fetch post on the right.

I've tweaked the headers to match the working Jquery example; looks like the data format's different. I'm guessing the form-urlencoded Content-Type is the format shown in the lower-left; Should I try to get my Object into that format? Chnaging the Content-Type to 'application/json' doesn't work.

edit: Looks like this is a server-side issue, probably due to the apparently two ways post data can be sent?

The Jquery/form-urlencoded data is requested in Django with
Python code:
dict(request.POST)
While the json/Fetch type is pulled with:
Python code:
json.loads(request.body)
And the working fetch code:

JavaScript code:
export function post(url: string, data, callback: Function=() => null) {
    fetch(url, {
        method: 'POST',
        headers: {
            "X-CSRFToken": getCookie('csrftoken'),
            "Content-Type": "application/json; charset=UTF-8",
            "Accept": "application/json",
            "X-Requested-With": "XMLHttpRequest"
        },
        credentials: 'include',
        body: JSON.stringify(data)
    })
        .then(result => result.json())
        .then(callback)
}

Dominoes fucked around with this message at 16:29 on Sep 5, 2017

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me
The issue looks to be that your backend wants Content-Type: "application/x-www-form-urlencoded", which is what that type=add&personId=126 is. What you are sending with fetch is Content-Type: "application/json".

Dominoes
Sep 20, 2007

Yea - I'm still trying to understand this, but have now replaced all my Jquery Ajax calls with calls to my post function above. Had to change server code as well per my above post (STS!) Added bonus of cleaner deserialization server-side: Had to do weird indexing I didn't understood before that's not required with this style.

necrotic
Aug 2, 2005
I owe my brother big time for this!
The jQuery one is using the same content type as a regular form post, which encodes the body like a query string in a URL. That's all there is to it: your fetch approach is using a different content type.

Dominoes
Sep 20, 2007

necrotic posted:

The jQuery one is using the same content type as a regular form post, which encodes the body like a query string in a URL. That's all there is to it: your fetch approach is using a different content type.
Given the data I like to transfer is JSON-like (JS Objects or Python dicts), this style makes more sense.

German Joey
Dec 18, 2004
Can anyone help me with Javascript build tools? I've developed a plugin for another library (leaflet.js) that I'd like to release on github, but the source code ended up being a lot longer than I originally predicted (~1200 lines now) so I'd like to split it up into multiple files. I don't need 'require' or anything of the sort, and my code is all plain, vanilla Javascript. I basically just want some standard build tool that will take my files and concat them together, and then minify the resulting file. What's the easiest way to do this with bower, or jake, or webpack, or rollup, or whatever the heck is the latest fashion these days?

geeves
Sep 16, 2004

German Joey posted:

Can anyone help me with Javascript build tools? I've developed a plugin for another library (leaflet.js) that I'd like to release on github, but the source code ended up being a lot longer than I originally predicted (~1200 lines now) so I'd like to split it up into multiple files. I don't need 'require' or anything of the sort, and my code is all plain, vanilla Javascript. I basically just want some standard build tool that will take my files and concat them together, and then minify the resulting file. What's the easiest way to do this with bower, or jake, or webpack, or rollup, or whatever the heck is the latest fashion these days?

1200 lines isn't too bad. If you're going to split it up, make sure it makes sense in context and that they could potentially be used independently with other projects.

Sometimes tools are overblown. You could try closure compiler or Uglify with a simple process.

Create build.sh (chmod 755)

code:
#!/usr/bin/env bash

# combine into single file
cat ./path-to-src/js/*.js > ./output/main.js

# use closure compiler / uglify to minify 
java -jar ./path-to/compiler.jar --js ./path-to-output/main.js --js_output_file ./path-to-output/main.min.js

Dominoes
Sep 20, 2007

If your'e OK with using typescript, this is a working webpack.config.js file:

JavaScript code:
module.exports = {
    entry: {
        main: "./src/main.tsx",
    },
    output: {
        filename: "[name].js",
        path: __dirname + "/dist"
    },

    // Enable sourcemaps for debugging webpack's output.
    devtool: "source-map",

    resolve: {
        // Add '.ts' and '.tsx' as resolvable extensions.
        extensions: [".ts", ".tsx", ".js", ".json", ".d.ts"]
    },

    module: {
        rules: [
            // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
            { test: /\.tsx?$/, loader: "awesome-typescript-loader" },

            // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
            { enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
        ]
    },

    // When importing a module whose path matches one of the following, just
    // assume a corresponding global variable exists and use that instead.
    // This is important because it allows us to avoid bundling all of our
    // dependencies, which allows browsers to cache those libraries between builds.
    externals: {
        "react": "React",
        "react-dom": "ReactDOM"
    }
}


// commented out in package.json post run..
// "postinstall": "../../node_modules/webpack/bin/webpack.js"
//    "webpack": "node_modules/webpack/bin/webpack.js --progress --colors --watch"
Then, you import other files with code like this:

JavaScript code:
import myPackage as name from 'my-package'

Adbot
ADBOT LOVES YOU

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

Dogcow posted:

But.. if you use ES6 syntax the native array filter method is actually shorter in most of your examples :confused:

[...]

Plus it's native so it's going to be the fastest implementation unless the browser is complete garbage somehow.

You're right, but I was not taking ES6 into account. We're not doing transpile stuff at the moment. The nice thing about lodash is that it lets you do all this stuff without worrying about which browser/platform you're targeting too much.

Performance-wise, lodash beats native in quite a few cases last I checked, though that's besides the point most of the time.

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