From 58ae9a2fcaca3ca762faf5f7daf5a675ba0d6fca Mon Sep 17 00:00:00 2001 From: Gabriele Corti <33316703+borntofrappe@users.noreply.github.com> Date: Fri, 12 Oct 2018 16:47:47 +0200 Subject: [PATCH 01/10] add backticks, remove unnecessary whitespace --- 34 - Promises.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/34 - Promises.md b/34 - Promises.md index b707f7a..0f08afd 100644 --- a/34 - Promises.md +++ b/34 - Promises.md @@ -4,7 +4,7 @@ First of all, `promise`s are often used when you're fetching a JSON API and doin Secondly, I'm going to be using a thing called `fetch` to be able to `fetch` in this JSON API. It's not a library, it's actually something built right into the browser. It returns a `promise`. -If you haven't heard of `fetch` before, it's very similar to `$.getJSON', if you've used jquery before, or '$.ajax', or any of these other AJAX libraries. Except, rather than having to load an external library, it's going to be built right into the browser. +If you haven't heard of `fetch` before, it's very similar to `$.getJSON`, if you've used jquery before, or `$.ajax`, or any of these other AJAX libraries. Except, rather than having to load an external library, it's going to be built right into the browser. Knowing that, let's jump into some examples of what a `promise` is. @@ -34,7 +34,6 @@ Let's take a look at a different example, but first a quick refresher about call ```js $('a').on('click',function() { alert('hey'); - }) ``` @@ -68,9 +67,7 @@ So let's fix that. We could probably just do an implicit return like the first p ```js const postPromise = fetch('http://wesbos.com/wp-json/wp/v2/posts'); -postPromise.then(data => data.json()).then(data => {console.log(data)} - -) +postPromise.then(data => data.json()).then(data => {console.log(data)}) ``` If we open it up in the console, we have the actual data that comes back from our blog. You see there's the content, excerpt, id, Wordpress slug, and all that stuff. @@ -90,7 +87,7 @@ postPromise Often people will put a `then` on its own line, just for readability's sake, but I've also added a `catch` function. -Remember, our `then` will only fire when the promise successfully comes back. If there is an error with the data that comes back, `catch` runs. Generally in your function, you'll have all of the `thens` that we need, it might be one, it might be four, but if we have a `catch` on the end, that will just catch any errors that happen anywhere along the way. +Remember, our `then` will only fire when the promise successfully comes back. If there is an error with the data that comes back, `catch` runs. In your function, you'll generally have all of the `then`s that we need, it might be one, it might be four, but if we have a `catch` on the end, that will just catch any errors that happen anywhere along the way. So let's pass some broken code, like a typo: @@ -107,4 +104,4 @@ postPromise In the console, we see our error here, along with some other errors that happened. But the `TypeError` gets thrown by this catch block here, which reports that it failed to `fetch` anything. -That's `fetch` at a very high level. \ No newline at end of file +That's `fetch` at a very high level. From c5369e580a079485a8d4cc29d9a8adfc0a0a5267 Mon Sep 17 00:00:00 2001 From: Gabriele Corti <33316703+borntofrappe@users.noreply.github.com> Date: Fri, 12 Oct 2018 16:53:04 +0200 Subject: [PATCH 02/10] propose change in variable name When testing the snippet -- on chrome -- using the `p` letter for the name of the variable will return this error: ```text Uncaught SyntaxError: Identifier 'p' has already been declared at :1:1 ``` --- 35 - Building your own Promises.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/35 - Building your own Promises.md b/35 - Building your own Promises.md index 6bc0bd6..fdbacc3 100644 --- a/35 - Building your own Promises.md +++ b/35 - Building your own Promises.md @@ -3,7 +3,7 @@ A `promise` is built into a lot of things in the browser like, `fetch` and `getU To create your own `promise`, you create a variable, and you store a new `promise` inside of it. A `promise` constructor takes one function here, which passes you `resolve` and `reject`... ```js -const p = new Promise((resolve, reject) => { +const myPromise = new Promise((resolve, reject) => { }); ``` @@ -19,11 +19,11 @@ Both `resove` and `reject` are called when you are ready to finish this `promise I'm going to call one immediately, and we're going to pass a string like "Wes is cool," because that's the data for this `promise`, and try to log that to the console using `.then`. ```js -const p = new Promise((resolve, reject) => { +const myPromise = new Promise((resolve, reject) => { resolve('Wes is cool') }); -p +myPromise .then(data => { console.log(data); }) @@ -32,7 +32,7 @@ p If we load this, we'll immediately we see "Wes is cool" in the console. This is because we created a `promise`, and then immediately resolved it by passing "Wes is cool" back to us. -It's really not that useful, but what you can probably see is that if we wanted to resolve something after some amount of time, maybe after some processing has been done. Maybe you wanted to do some processing on the background that's really intensive, like an AJAX request for data. There's a whole bunch of different use cases for when you would want to use a `promise`. +It's really not that useful, but what you can probably see is that if we wanted to resolve something after some amount of time, maybe after some processing has been done, we can use promises. Maybe you wanted to do some processing on the background that's really intensive, like an AJAX request for data. There's a whole bunch of different use cases for when you would want to use a `promise`. Essentially it all boils down to "I don't want to stop JavaScript from running, I just want to start this thing, and then when it comes back I'll deal with the actual result." @@ -40,13 +40,13 @@ Let's see what happens when we put a setTimeout on here for one second. ```js -const p = new Promise((resolve, reject) => { +const myPromise = new Promise((resolve, reject) => { setTimeout(() => { resolve('Wes is cool') }, 1000); }); -p +myPromise .then(data => { console.log(data); }) @@ -57,13 +57,13 @@ If we load this, you'll notice that it doesn't pop up immediately. Similarly, we could also call `reject` on it: ```js -const p = new Promise((resolve, reject) => { +const myPromise = new Promise((resolve, reject) => { setTimeout(() => { reject('Err Wes isn\'t cool'); }, 1000); }); -p +myPromise .then(data => { console.log(data); }) @@ -74,13 +74,13 @@ But if we run that, you'll see that we get an error: "Uncaught (in promise) "Err Why is that uncaught in promise? Because we didn't `catch` it, right? We should `catch` the error, using `catch` and `console.error`. ```js -const p = new Promise((resolve, reject) => { +const myPromise = new Promise((resolve, reject) => { setTimeout(() => { reject('Err Wes isn\'t cool'); }, 1000); }); -p +myPromise .then(data => { console.log(data); }) @@ -95,13 +95,13 @@ Ideally what you do is you throw in an error object, not just a string, like thi ```js -const p = new Promise((resolve, reject) => { +const myPromise = new Promise((resolve, reject) => { setTimeout(() => { reject(Error('Err Wes isn\'t cool')); }, 1000); }); -p +myPromise .then(data => { console.log(data); }) From 03976c60a2f9cb73e14bb69d815d4da85a426d5e Mon Sep 17 00:00:00 2001 From: Gabriele Corti <33316703+borntofrappe@users.noreply.github.com> Date: Fri, 12 Oct 2018 17:02:30 +0200 Subject: [PATCH 03/10] fix capitalization, spelling, code snippet On line 114, I do believe `author.Details` is actually supposed to actually be `authorDetails` --- 36 - Chaining Promises + Flow Control.md | 27 ++++++++++++------------ 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/36 - Chaining Promises + Flow Control.md b/36 - Chaining Promises + Flow Control.md index 7f4dc1b..f96f668 100644 --- a/36 - Chaining Promises + Flow Control.md +++ b/36 - Chaining Promises + Flow Control.md @@ -1,4 +1,4 @@ -Another useful case for `Promise` is when you need some sort of flow control. This is an example where you would probably find out on a back end and maybe something like Node.js, when you are querying a database. +Another useful case for `Promise` is when you need some sort of flow control. This is an example you would probably find on a back end project and maybe with something like Node.js, when you are querying a database. ```js const posts = [ @@ -22,17 +22,16 @@ We are going to use these two arrays to simulate a connection to a database that What we're going to do is we're going to create two separate functions that both going to return a `Promise` each, and then we are going to chain them together. +In setting up our function, we want it to look up in our database for the post with an `id` of 1. + ```js function getPostById(id) { - } getPostById(1) ``` -In setting up our function, we want it to look up in our database for the post with an `id` of 1. - -The first thing we need is a `Promise`, because we cannot access it from our database immediately. It has to do a round trip around back and forth to the database: +The first thing we need is a `Promise`, because we cannot access it from our database immediately. It has to do a round trip to the database: ```js function getPostById(id) { @@ -53,7 +52,7 @@ getPostById(1) We are going to loop over every single post. Then, when the `id` matches what we want in our function, 1, we're going to find the `post` there for our control flow. The `if` is looking for a `post` matching the `id`. Once it does, it will `resolve` and give the `promise` to `post`, otherwise we are going to `reject` and say `'No Post Was Found!'`. -In order to simulate this, so it takes time, what we can do is as you can just wrap this in a `SetTimeOut`, which will sort of simulate the taking 200 ms round trip. +In order to simulate this, so it takes time, what we can do is as you can just wrap this in a `setTimeout`, which will sort of simulate the taking 200ms round trip. If you like to run it instantly, you don't have to do this, but it's totally up to you. @@ -61,7 +60,7 @@ If you like to run it instantly, you don't have to do this, but it's totally up function getPostById(id) { // create a new promise return new Promise((resolve, reject) => { - // using a settimeout to mimic a database + // using setTimeout to mimic a database setTimeout(() => { //find the post we want const post = posts.find(post => post.id === id); @@ -81,9 +80,9 @@ getPostById(1) }) ``` -There we go. If we run this, we'll see there is a post immediately as an Object.. We get `postById(1)`'s result, my post. +There we go. If we run this, we'll see there is a post immediately as an Object. We get `postById(1)`'s result, my post. -We want to do this thing that I like to call 'hydrating'. In our `posts` array, where the author of this post is just a string, `'Wes Bos'`, but I want to replace it with the the `author` object, which has my name as well as my twitter and bio. +We want to do this thing that I like to call 'hydrating'. In our `posts` array, where the author of this post is just a string, `'Wes Bos'`. I want to replace it with the the `author`'s object, which has values for the author's `name` as well as `twitter` and `bio`. I'm going to create a new function called `hydrateAuthor`, which is going to take in the post, and then return in our getPostbyId function as a `Promise`. What's great about that is that if we return a `Promise` inside of a `.then`, we're allowed to chain another `.then` on to the next line. The whole thing looks something like this: @@ -91,7 +90,7 @@ I'm going to create a new function called `hydrateAuthor`, which is going to tak function getPostById(id) { // create a new promise return new Promise((resolve, reject) => { - // using a settimeout to mimic a database + // using setTimeout to mimic a database setTimeout(() => { //find the post we want const post = posts.find(post => post.id === id); @@ -112,7 +111,7 @@ function hydrateAuthor(post) { const authorDetails = authors.find(person => person.name === post.author); if(authorDetails) { // "hydrate" the post object with the author object - post.author = author.Details; + post.author = authorDetails; resolve(post); } else { reject(Error('Can not find the author')); @@ -122,10 +121,10 @@ function hydrateAuthor(post) { getPostById(1) .then(post => { - console.log(post); return hydrateAuthor(post); }) .then(post => { + console.log(post); }) .catch(err => { console.error(err); @@ -134,11 +133,11 @@ getPostById(1) Let's step through all of that new code. -We create our `hydrateAuthor` function that takes in the `post`. We create a new `Promise`, where we find the `author`. If there is an `author`, then we `hydrateAuthor` on our post object, which adds the `author` object to the `post`. Otherwise, it's rejected. +We create our `hydrateAuthor` function that takes in the `post`. We create a new `Promise`, where we find the `author`. If there is an `author`, then we `hydrateAuthor` on our post object, which adds the `author` object to the `post`. Otherwise, the promise is rejected. On the end of the function, I've removed the initial `console.log`, because we don't really need it anymore, We're also going to see a `catch` for error handling. If there is an error thrown in anytime, we should be able to show the error, and allow us to debug it. -If we run that in the console, you'll see that we get the is `hydrateAuthor` version of the post. Our `author` is an object that contains the `bio`, `name`, and `twitter` for whichever author wrote the post. +If we run that in the console, you'll see that we get the `hydrateAuthor` version of the post. Our `author` is an object that contains the `bio`, `name`, and `twitter` for whichever author wrote the post. The `catch` allows us to find errors, too. If we run `getPostById`, we'll see an error that no post was found. Similarily, if we have a typo for an author's name, we get the error, 'Cannot find the author'. From 980747eb85219b90d365a8feb6fbfab28b6de63e Mon Sep 17 00:00:00 2001 From: Gabriele Corti <33316703+borntofrappe@users.noreply.github.com> Date: Fri, 12 Oct 2018 17:07:22 +0200 Subject: [PATCH 04/10] Improve wording, add backticks --- 37 - Working with Multiple Promises.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/37 - Working with Multiple Promises.md b/37 - Working with Multiple Promises.md index 8188904..636c410 100644 --- a/37 - Working with Multiple Promises.md +++ b/37 - Working with Multiple Promises.md @@ -1,4 +1,4 @@ -The last example we 'stepped', which is to say that we waited for the post to come back before we actually found the author because we needed to know who the author of the post was before we could hydrate the author. The first thing needed to happen before the second thing could happen. It's sort of a waterfall approach. +In the last example we 'stepped', which is to say that we waited for the post to come back before we actually found the author. This because we needed to know who the author of the post was before we could hydrate the author's object. The first thing needed to happen before the second thing could happen. It's sort of a waterfall approach. In some cases, you just want to fire them all off at the exact same time, because they're not dependent on each other, and you want to get two things back, or four things back, as soon as possible. @@ -43,7 +43,6 @@ Promise console.log(responses); }); ``` -[2:04] In the console, you should notice that it takes two seconds to come back. This is because every `Promise` in the function has to finish before we can run the `.then` to get a result. In this case, our longest `promise` takes two seconds. So for example, if a `promise` takes takes 10 seconds, your `Promise.all` is going to take 10 seconds to resolve. If one takes 15 seconds, it's going to take 15 seconds. The slowest response decides how long these things should actually take. @@ -66,7 +65,7 @@ Now, we have two separate variables, one with our `weather`, one with our `tweet However, it's probably not a good idea to name this `weather` and `tweets`. Why? Because our `promises` are named `weather` and `tweets`, so maybe call it `weatherInfo` and `tweetsInfo`. -Let's actually do some with some real data here. +Let's actually do something with some real data here. We need two APIs. If you work with an API during the day, I encourage you to go grab that API. Otherwise, you can use the ones I've got right here: @@ -75,7 +74,7 @@ const postsPromise = fetch('http://wesbos.com/wp-json/wp/v2/posts'); const streetCarsPromise = fetch('http://data.ratp.fr/api/datasets/1.0/search/?q=paris'); ``` -I've got `postPromise` here, which is going to go to my blog and grab all of my latest posts, which I've used before. We also have the `streetCarsPromise`, which is going to go and fetch some data from the Paris transit system. +I've got `postPromise` here, which is going to go to my blog and grab all of my latest posts, which we've used before. We also have the `streetCarsPromise`, which is going to go and fetch some data from the Paris transit system. We need to resolve each `promise`, or rather, they will resolve themselves, but we need to listen to when they are both resolved. @@ -115,9 +114,9 @@ Promise.all([postsPromise, streetCarsPromise]) ``` -What we can do is we can return a promise.all again, and then we will take each of these things, which is the responses, and we can just map over them and call .json on each one. +What we can do is we can return a `Promise.all` again, and then we will take each of these things, which is the responses, and we can just map over them and call .json on each one. -We'll say response, and we will return response.json. Why do we have to call this res.json? Why can't we just say json.parse around, res.body or something like that? +We'll say response, and we will return response.json. Why do we have to call this `res.jso`n? Why can't we just say `json.parse` around, `res.body` or something like that? We actually use `res` instead of `responses` here, because there are many different types of data that could come back. If you [check out the documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch), you can see that the data can come back as an `.arrayBuffer()`, `.blob()`, `.json()`, `.text()`, or `.formData()`. @@ -125,7 +124,7 @@ Don't just assume that your APIs or your AJAX requests are always going to be js What are we doing? Our response is, in this case, in an array, and `.map` takes every item out of an array, does something to it, and then returns a new array. -What we're doing here, is we're taking the array of `responses` and taking each one and calling `.json()` on it. This returns a second promise, which we can call `.then` on, and that should then, responses, that should give us some real data: +What we're doing here, is we're taking the array of `responses` and taking each one and calling `.json()` on it. This returns a second promise, which we can call `.then` on, and that should then, through `responses`, give us some real data: ```js const postsPromise = fetch('http://wesbos.com/wp-json/wp/v2/posts'); @@ -141,4 +140,4 @@ Promise.all([postsPromise, streetCarsPromise]) ``` So if we open this up, we'll see our API data in an array. In this case, we got about 10 posts, and an object containing some information about the Paris transit system. -So what we've done overall here is using a `Promise.all` on our initial promises, `postsPromise` and `streetCarsPromise`. Then when both of those promises come back, we run `.json()` on all of them. Then, when both of those come back from being turned from just regular data into json, which is instant, then this final `promise` then is called and we can do whatever it is that we want with that data. \ No newline at end of file +So what we've done overall here is using a `Promise.all` on our initial promises, `postsPromise` and `streetCarsPromise`. Then when both of those promises come back, we run `.json()` on all of them. Then, when both of those come back from being turned from just regular data into json, which is instant, then this final `promise` then is called and we can do whatever it is that we want with that data. From 3cd2928178c0271238764b33f0055f4d5203714b Mon Sep 17 00:00:00 2001 From: Gabriele Corti <33316703+borntofrappe@users.noreply.github.com> Date: Fri, 12 Oct 2018 17:14:08 +0200 Subject: [PATCH 05/10] Improve wording, remove white spaces. --- 39 - Getting Started with ESLint.md | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/39 - Getting Started with ESLint.md b/39 - Getting Started with ESLint.md index 05ec439..5070c01 100644 --- a/39 - Getting Started with ESLint.md +++ b/39 - Getting Started with ESLint.md @@ -7,20 +7,20 @@ ESLint essentially, it hurts your feelings. It looks at your code and tells you At first it seems a little bit overwhelming because it tells you everything is wrong with your code, but it's all a matter of: - Getting it configured properly for your coding style -- Actually understanding why are these errors happening. +- Actually understanding why are these errors happening. In the long run, it's going to make you a much better developer. It includes a [demo](http://eslint.org/demo/) that you can try out and see what comes back. For example, "Strings must use doublequote" is a habit I have that it doesn't like, or it finds extra spaces and stuff like that. -ESLint finds all kinds of different stuff and catch code quality problems before they actually cause an issue. +ESLint finds all kinds of different stuff and catches code quality problems before they actually cause an issue. I'm going to go through setting it up, getting it installed, and then I'm going to show you how do you configure it and what is your process for actually understanding how it works. In my experience, the first time someone uses it takes maybe an hour or two to get it really where they like it, but you're going to be writing better code and you're going to earn that time back after no time. -There's a few things we need to in order to get started. +There are a few things we need to in order to get started. -First of all, you need nodejs and npm installed. Chances are, most of you already have this installed. If you don't know, head on over to your terminal and check your versions of node and npm: +First of all, you need Node.js and npm installed. Chances are, most of you already have this installed. If you don't know, head on over to your terminal and check your versions of node and npm: ```bash $ node -v @@ -28,7 +28,7 @@ $ npm -v ``` In order to continue, you'll need to make sure that you have version 4.0 or higher. If you have an old version or you get an error, like `node is not a command`, go to [nodejs.org](http://nodejs.org) and download the latest version. - Once you have that installed, we need to install ESLint. The way that ESLint is going to work is we're going to type `eslint` at the command line and point it at a file and give us our errors and problems in the file. +Once you have that installed, we need to install ESLint. The way that ESLint is going to work is we're going to type `eslint` at the command line and point it at a file and give us our errors and problems in the file. To install that, use your terminal: @@ -56,7 +56,7 @@ $ eslint bad-code.js What that's going to do is it's going to scan our file and tell us what is actually wrong with it. One of the things you might want to do is configure ESLint to account for arrow functions, because it doesn't do that right away. This is where the settings for ESLint actually start to come in handy. -ESLint settings can be doneglobally on your computer and or you can do it project by project. +ESLint settings can be done globally on your computer and or you can set them project by project. A lot of people prefer to do it project by project because there's different coding styles depending on which project or team you are working with. We are going to go ahead and create what's called a `.eslintrc` file in the folder right here, and that's going to hold all of our actual settings. @@ -64,11 +64,11 @@ A lot of people prefer to do it project by project because there's different cod $ touch .eslintrc ``` -That will have created a new file called `.eslintrc`. Sometimes some computers hide files that start with a dot, so you might not immediately see it in your Finder or Windows Explorer. However, if you go to your editor and open that folder you should see the `.eslintrc` file. +That will create a new file called `.eslintrc`. Sometimes some computers hide files that start with a dot, so you might not immediately see it in your Finder or Windows Explorer. However, if you go to your editor and open that folder you should see the `.eslintrc` file. Inside of the empty `.eslintrc` file we are going to write json, which is full of all of our settings. To write json, you open up an object and we now need to specify a whole bunch of options that we need. What are the possible options? Well, ESLint is full of options, and it can be a little bit overwhelming. -If we head back over to the [ESLint demo page](http://eslint.org/demo/) and scroll down a bit, you can see some of the options, like Environments. Are you writing node, Mocha, Jasmine, PhantomJS, QUnit, or whatever. There's also all these different rules that you can have. We'll look at a shortcut way, because there's no way you have time to make a decision about every single one of the possible rules. +If we head back over to the [ESLint demo page](http://eslint.org/demo/) and scroll down a bit, you can see some of the options, like Environments. Are you writing node, Mocha, Jasmine, PhantomJS, QUnit, or whatever?. There's also all these different rules that you can have. We'll look at a shortcut, because there's no way you have time to make a decision about every single one of the possible rules. So let's set up some rules in our `.eslintrc` file. @@ -83,9 +83,9 @@ So let's set up some rules in our `.eslintrc` file. } ``` -Since we're writing json here, you must use double quotes for your keys For the sake of this example, we're only going to use ES6 and browser. +Since we're writing json here, you must use double quotes for your keys. For the sake of this example, we're only going to use ES6 and browser. -However, you can always go to the [ESLint.org's documentation and check out the possible rules](http://eslint.org/docs/rules),as well as if you check out [Configuring ESLint](http://eslint.org/docs/user-guide/configuring), you're going to see a list of all of the possible environments. +However, you can always go to the [ESLint.org's documentation and check out the possible rules](http://eslint.org/docs/rules). If you check out [Configuring ESLint](http://eslint.org/docs/user-guide/configuring), you're also going to see a list of all of the possible environments. Now, I've set the environment ES6 to be true, and now we should be able to run ESLint on our file. @@ -108,13 +108,12 @@ Now if we go back to our terminal and re-run that that on your code file, you'll As you go back through your code, you'll be able to resolve each error reported by ESLint and make decisions on how to refactor your code. After each resolution, you'll be able to reduce your errors. -By default, ESLint recommends against using stuff like `console.log`, which makes sense. However, we're saying, "It's fine that I'm using console, I know what I'm doing. I'll make sure that it take them out, or maybe I'll have another ESLint that that role will be set on development and not in production." +By default, ESLint recommends against using stuff like `console.log`, which makes sense. However, we're saying, "It's fine that I'm using console, I know what I'm doing. I'll make sure that to take them out, or maybe I'll have another ESLint rule that will be set on development and not in production." But to turn it off, we can add custom rules to our `.eslintrc` file. Before we do that, how do you actually work with these rules? For `console.log`, the rule is `no-console`, which ESLint will tell us. - So if we [check out the rule](http://eslint.org/docs/rules/no-console), spend some time reading why this rule is set. Don't just turn it off immediately because it's annoying and you think you're right. Maybe just spend some time and say, "Maybe I shouldn't be using this rule, or maybe I shouldn't be writing my code in this way. Why is this possibly bad?" Read through why they think that maybe this rule should be turned on. It looks at some examples as to what you shouldn't be using, and then finally there is when not to use it. @@ -144,4 +143,4 @@ You have a few options on how to set your rule. you can use `"off"`, `"warn"`, o What our `"rules"` line is doing is it's taking all the rules from the ESLint recommended set, and then we're taking the no-console rule and applying our own setting. It's like CSS, where you have a base framework here and then you overwrite your own specific ones. -There's all kinds of stuff that you can do to tell ESLint to warn you about, especially stylistic ones. In the next post we'll look at Airbnb's default rules, which are a little bit more strict but will allow you to write much better code. \ No newline at end of file +There's all kinds of stuff that you can do to tell ESLint to warn you about, especially stylistic ones. In the next post we'll look at Airbnb's default rules, which are a little bit more strict but will allow you to write much better code. From 8b6820c154b6d9eaf049751af262330917f7c5b7 Mon Sep 17 00:00:00 2001 From: Gabriele Corti <33316703+borntofrappe@users.noreply.github.com> Date: Fri, 12 Oct 2018 17:24:08 +0200 Subject: [PATCH 06/10] Improve wording, add backticks Pending issue: when setting the exceptions to the `unused-var` rule, a string that starts with err is described with a tilde `~`. However, later in the text, the same construct is described with a caret `^`. Considering regular expressions I think it's likely a caret, but I am not 100% sure. --- 40 - Airbnb ESLint Settings.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/40 - Airbnb ESLint Settings.md b/40 - Airbnb ESLint Settings.md index c0f7576..5d2de4d 100644 --- a/40 - Airbnb ESLint Settings.md +++ b/40 - Airbnb ESLint Settings.md @@ -1,4 +1,4 @@ -The engineers at Airbnb have created a really nice JavaScript style guide that shows you how to write ES6 in a way that is consistent across all of your projects. It does things like tell you to use `const` and when to use `let`, and how to write your `if` statements, and where do you semicolons and that kind of stuff. Their ESLint file is a way to enforce their style guide. +The engineers at Airbnb have created a really nice JavaScript style guide that shows you how to write ES6 in a way that is consistent across all of your projects. It does things like tell you to use `const`, when to use `let`, how to write your `if` statements, where to include semicolons and that kind of stuff. Their ESLint file is a way to enforce their style guide. A lot of people adopt the Airbnb style of coding and then they'll use their own settings on top of it, and that's exactly what we're going to do. We're going to implement the Airbnb style guide and then we're going to go through in and pick off little things where we think that our style differs a little bit. @@ -42,7 +42,7 @@ Once you have that installed, we can run ESLint against our `badcode.js` file, a Many of our errors in `badcode.js` have to do with spacing, where we get `A space is required after ','`, or `A space is required before '}'`, Those are just such minor little things that ESLint will actually fix immediately for you if you run `eslint bad-code.js --fix`. Instead of having to go through our file and fix each spacing one by one, it's taken care of. -By running that, we're able to go from 12 problems down to 2 problems. It's going to fix almost all of those little spacing issues for us. Howeever, now we've got two other problems here that we need to take care of. +By running that, we're able to go from 12 problems down to 2 problems. It's going to fix almost all of those little spacing issues for us. However, now we've got two other problems here that we need to take care of. First of all `unexpected var use let or const instead`, which is pretty straight forward. In our example, I have `var weather = new Promise`. So instead of `var`, should I use `let` or should I use `const`? Now the question here is will I ever reassign `weather`, does it need to update itself or is it always going to hold this `new Promise`? @@ -62,7 +62,7 @@ Promise ``` The issue here is that we have a block statement and then all that block is doing is that `return Promise.all`. What it actually should be telling is that you should use the implicit return if all that you're going to be doing is opening up a block and returning one thing from it. -If we check out our [ESLint documentation](http://eslint.org/docs/rules/arrow-body-style), it says: "Arrow functions have two formats. They may be defined with a block or it's a single expression" and it shows us some examples of when you wouldn't want to do it and when you would want to use it. I like that error, so I'm going to not turn it off in here but I'm going to actually go ahead and fix that myself. We don't need a block here or a return, we don't need the opening block. +If we check out our [ESLint documentation](http://eslint.org/docs/rules/arrow-body-style), it says: "Arrow functions have two formats. They may be defined with a block or it's a single expression" and it shows us some examples of when you would and would not use it. I like that error, so I'm going to not turn it off in here but I'm going to actually go ahead and fix that myself. We don't need a block here or a return, so we don't need the opening block. ```js Promise @@ -75,13 +75,13 @@ Promise Back over in our terminal, we can rerun ESLint, and it should like celebrate or something and tell you that you did a good job but it's simply just gives you your command prompt, and nothing else. -So far we've been working with the local `.eslintrc` file and that means that we have an ESLint file for every single project that we work on. That can be really handy when you have different coding styles amongst different projects or different teams that you work with. However, it's also helpful to have a global `.eslintrc` file, which if you do not have one anywhere inside of your project, it's going to use your global one as sort of a default. +So far we've been working with the local `.eslintrc` file and that means that we have an ESLint file for every single project that we work on. That can be really handy when you have different coding styles amongst different projects or different teams that you work with. However, it's also helpful to have a global `.eslintrc` file, used by default if you do not have one anywhere inside of your project. I really like to do that because it means I don't have to create an ESLint file for every single project or I have one that I can copy/paste into new projects that I'm going to put up to GitHub and expect others to follow that coding style. I'm going to open up my global one and it lives in your home directory. -What's your home directory? Well, it depends. On a mac, it's generally your username directory, on Windows machine it's under `C:\users\username`, where user name. +What's your home directory? Well, it depends. On a mac, it's generally your username directory, on Windows machine it's under `C:\users\username`, where username changes according to the name of the user. -Your home directory is `~`, If you do not have one you can use your terminal to create one by typing `touch .eslintrc`, but if you already do have one you can just open it up in your editor. +Your home directory is `~`. If you do not have one you can use your terminal to create one by typing `touch .eslintrc`, but if you already do have one you can just open it up in your editor. I'm going to show you exactly what is inside of mine: @@ -111,12 +111,12 @@ I'm going to show you exactly what is inside of mine: } ``` -So usinging Airbnb work in the browser, Node.js, and sometimes I use jQuery so I've turned all of those on. +So using Airbnb and working with the browser, Node.js, and sometimes jQuery, I've turned all of those on. Then I have all of these rules that I have been working with, and I take all the rules from Airbnb and then these are the ones where I don't necessarily agree a hundred percent with Airbnb's implementation. These are just the once that I've sort of taken over. -Looking at `"comma-dangle"` as our example, without my rules, I can write some code like: +Looking at `comma-dangle` as our example, without my rules, I can write some code like: ```js const wes = { @@ -130,7 +130,7 @@ That's actually one that I have turned to a warning in my regular ESLint rules, What I would do is I turn that to an actual warning, which I've done by setting it to `1` -Back to this `comma-dangle here`, what is the actual error? Sometimes people will say that you should absolutely always put a comma even if you don't have another line, like here on the end of `cool: true`: +Back to this `comma-dangle` here, what is the actual error? Sometimes people will say that you should absolutely always put a comma even if you don't have another line, like here on the end of `cool: true`: ```js const wes = { @@ -150,8 +150,8 @@ app.get('/accounts', (req, res, next) => { }); ``` - I like to set up all my routes like that and I might not necessarily use `res` or `next` but I like to have them there in case I need to use them again. What I've done is I've set them to simply just give me a warning when I haven't use a variable. However, if I use res, next or anything that starts with error then don't worry about that at all. + I like to set up all my routes like that and I might not necessarily use `res` or `next` but I like to have them there in case I need to use them again. What I've done is I've set them to simply just give me a warning when I haven't use a variable. However, if I use `res`, `next` or anything that starts with `err` then don't worry about that at all. -I'm not going to sit here and go through every single rule in all of ESLint and sort of explaining what you should and shouldn't use. What I honestly think that you should do is start with the Airbnb set, and just start writing code and over the next like couple of days what's going to happen is you're going to come out, you're going to trip over errors, you're going to say, "Why is that error there?" +I'm not going to sit here and go through every single rule in all of ESLint and sort of explaining what you should and shouldn't use. What I honestly think that you should do is start with the Airbnb set, and just start writing code and over the next like couple of days. What's going to happen is you're going to come out, you're going to trip over errors, you're going to say, "Why is that error there?" -Go ahead and go to the ESLint docs, research it, see if it's actually a rule that makes sense for you and your team. If it is, make sure you keep it in your rules. If it doesn't, take it out of your rules or set it to warn instead of actual error. A lot of times people ask me, "Hey, Wes can I just take your ESLint?" I think that is OK, however I maybe even prefer that you just start with nothing and just learn and build your own as you start to go through this. \ No newline at end of file +Go ahead and go to the ESLint docs, research it, see if it's actually a rule that makes sense for you and your team. If it is, make sure you keep it in your rules. If it doesn't, take it out of your rules or set it to warn instead of actual error. A lot of times people ask me, "Hey, Wes can I just take your ESLint?" I think that is OK, however I maybe even prefer that you just start with nothing and just learn and build your own as you start to go through this. From 6e6008683e0e18022314a3d00b28807dd5199566 Mon Sep 17 00:00:00 2001 From: Gabriele Corti <33316703+borntofrappe@users.noreply.github.com> Date: Fri, 12 Oct 2018 17:26:23 +0200 Subject: [PATCH 07/10] Add missing characters, separate complex sentence. --- 42 - ESLint Plugins.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/42 - ESLint Plugins.md b/42 - ESLint Plugins.md index b7d10b1..f72fc12 100644 --- a/42 - ESLint Plugins.md +++ b/42 - ESLint Plugins.md @@ -1,4 +1,4 @@ -One really cool thing about ESLint is that there is a fantastic community that has built great plugins for ESLint, and if you take a look at [his awesome ESLint GitHub repo](https://github.com/dustinspecker/awesome-eslint), you'll see that there is a listing of all kinds of different plugins that you can use depending on what type of JavaScript that you write every single day. +One really cool thing about ESLint is that there is a fantastic community that has built great plugins for ESLint, and if you take a look at [this awesome ESLint GitHub repo](https://github.com/dustinspecker/awesome-eslint), you'll see that there is a listing of all kinds of different plugins that you can use depending on what type of JavaScript that you write every single day. Whether you're writing Angular or Backbone, or you need to specifically lint your Jasmine docs, every time you write stuff that is for a different framework, you can have a little bit of difference in your style rules. Chances are that someone has already built some sort of linting plugin for that specific framework. @@ -6,7 +6,7 @@ A plugin I use a lot is for when I need to lint my JavaScript that is inside of How do I lint code that as not inside of a JS file? If you try to run ESLint code right through HTML, it's going to give you an error and say "This ESLint doesn't understand HTML." We need a plugin that's going to strip your JavaScript out of your script tags, lint it, and tell you what's wrong with it. Same goes for markdown. -Let's take a look at how to use those two specific plugins here. I going to go into here and find the HTML. Looks like the HTML is actually not in here, so I'm going to say ESLint HTML, [which is actually hosted over on NPM as a package](https://www.npmjs.com/package/eslint-plugin-html). As a note, this also works in .erb files for Ruby on Rails, .php files, and a whole lot of other file formats as well. +Let's take a look at how to use those two specific plugins here. I'm going to go into here and find the HTML. Looks like the HTML is actually not in here, so I'm going to say ESLint HTML, [which is actually hosted over on NPM as a package](https://www.npmjs.com/package/eslint-plugin-html). As a note, this also works in `.erb` files for Ruby on Rails, `.php` files, and a whole lot of other file formats as well. Remember, to install an npm package, you can use `npm install eslint-plugin-html -g` to install it globally, or however you need to install the plugin. @@ -40,8 +40,8 @@ Once again, you add the plugin you want to use in your array, which will look so ``` Like before, you can run ESLint against your markdown files using something like `eslint *.md` to look at all of your markdown files in a specific directory. -Using that `*.md` is something called "glob pattern" if you have ever used gulp-matching or any other sort of matching, you can pass a list of `*.md`, or `*.js`, or `*.html` or whatever. You can also pass it `--ext`. If you wanted to know all of the options for ESLint, simply type `eslint --help` and it will give you a list of all of the possible ways where you can search for different kinds of extensions, and pass it a specific ESLint file. +Using that `*.md` is something called "glob pattern". If you have ever used gulp-matching or any other sort of matching, you can pass a list of `*.md`, or `*.js`, or `*.html` or whatever. You can also pass it `--ext`. If you wanted to know all of the options for ESLint, simply type `eslint --help` and it will give you a list of all of the possible ways where you can search for different kinds of extensions, and pass it a specific ESLint file. Those are plugins. Take a look through it and see which plugins probably work best with your workflow, but those are the two that you probably will run into at some point, and they're very helpful to use. -One little thing I should mention that is currently, at the time of recording, you cannot use `--fix` on HTML or markdown files. `--fix` only works on pure `.js` files. Hopefully that will get fixed soon, but don't spend any time trying to get it to work because it's not possible. \ No newline at end of file +One little thing I should mention that is currently, at the time of recording, you cannot use `--fix` on HTML or markdown files. `--fix` only works on pure `.js` files. Hopefully that will get fixed soon, but don't spend any time trying to get it to work because it's not possible. From 8dba2031fc64d32770831516f534580a7543f04b Mon Sep 17 00:00:00 2001 From: Gabriele Corti <33316703+borntofrappe@users.noreply.github.com> Date: Fri, 12 Oct 2018 17:28:29 +0200 Subject: [PATCH 08/10] Remove repetition in describing the errors. Fix initial grammar error. --- ... Only Allow ESLint Passing Code into your git repos.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/44 - Only Allow ESLint Passing Code into your git repos.md b/44 - Only Allow ESLint Passing Code into your git repos.md index a07eb82..0710fbf 100644 --- a/44 - Only Allow ESLint Passing Code into your git repos.md +++ b/44 - Only Allow ESLint Passing Code into your git repos.md @@ -1,4 +1,4 @@ -If you work on a team or an open source project with other people, it's helpful to have an ESLint file right in your Git repo, and then you can have what's called a Git hook, which will not allow anyone to commit any code, unless it first passes the ESLint rule. That's really important because than you're going to keep up code quality for everyone that touched that project. +If you work on a team or an open source project with other people, it's helpful to have an ESLint file right in your Git repo, and then you can have what's called a Git hook, which will not allow anyone to commit any code, unless it first passes the ESLint rule. That's really important because then you're going to keep up code quality for everyone that touched that project. Starting from scratch, let's say there's no predefined folder you're going to get. Go ahead and use the folder you've been testing out ESLint so far in, because we'll need that as a base. Open the folder in your terminal and type `git init ES6git`. It should make a folder called `ES6git` @@ -28,9 +28,7 @@ But as soon as I hit enter or return, we get our error message and our commit is So with our check, you get the same four errors here that we got in our manual lint earlier. What we have to do is go back to our code here, and we look at all the different errors. -First error, unexpected var. I should have used const. Then next error, X is defined but never used, so I should have said console.log X. Infix operators must be spaced. I forgot the space there, and missing semicolon. I've got to put a semicolon on the end there. - -So we get `Unexpected varm use let or const instead`, `'x' is defined but never used`, `Infix operators must be spaced`, and of course, our `Missing semicolon`. +First error, `unexpected var`. I should have used `const`. Then next error, `x is defined but never used`, so I should have said `console.log(x)`. `Infix operators` must be spaced. I forgot the space there, and missing semicolon. I've got to put a semicolon on the end there. So let's fix it up: @@ -39,4 +37,4 @@ const x = 100; console.log(x); ``` -If we go to add and commit, and include our message again, you'll see you didn't have any problems with our ESLint, so everything went ahead, and now your master branch is in a clean state. \ No newline at end of file +If we go to add and commit, and include our message again, you'll see you didn't have any problems with our ESLint, so everything went ahead, and now your master branch is in a clean state. From 1c377fcfbabf8d932453be890e7496a6fc43dd73 Mon Sep 17 00:00:00 2001 From: Gabriele Corti <33316703+borntofrappe@users.noreply.github.com> Date: Fri, 12 Oct 2018 17:33:36 +0200 Subject: [PATCH 09/10] Add backticks --- 31 - Spreading into a function.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/31 - Spreading into a function.md b/31 - Spreading into a function.md index 85aaae1..d5a85f2 100644 --- a/31 - Spreading into a function.md +++ b/31 - Spreading into a function.md @@ -1,4 +1,4 @@ -A really great use case for spreads is when you spread into a function. Now, let's take a look at this example. I've got my inventors array right here, and I want to take the items from newInventors and put them into Inventors. I don't want a third array. I don't want to overwrite the entire array. I just want to tack them onto the end. +A really great use case for spreads is when you spread arguments into a function. Now, let's take a look at this example. I've got my `inventors` array right here, and I want to take the items from `newInventors` and put them into `inventors`. I don't want a third array. I don't want to overwrite the entire array. I just want to tack them onto the end. ```js const inventors = ['Einstein', 'Newton', 'Galileo']; @@ -45,7 +45,7 @@ Now we don't have to worry about any of that apply, or this, or any of these thi We simply just spread right into the functions. We've been spreading into arrays, but you can also spread into a function where every single item of the array is going to be used as an argument. -Let's build another example ourselves where we have a function that says in an alert "Hey there first last." +Let's build another example ourselves where we have a function that says in an alert "Hey there " followed by two variables labeled `first` and `last`. ```js const name = ['Wes', 'Bos']; From 81f7244efb7d74c829820d28ce03ee35a2dd3872 Mon Sep 17 00:00:00 2001 From: Gabriele Corti <33316703+borntofrappe@users.noreply.github.com> Date: Fri, 12 Oct 2018 17:38:34 +0200 Subject: [PATCH 10/10] Add missing word, update snippet The last instance of the `convertCurrency` function refers to `tax` and `tip`, but doesn't actually use them. 1.54$ on line 11 is modified to match the value in the following snippet. --- .....rest param in Functions and destructuring.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/32 - The ...rest param in Functions and destructuring.md b/32 - The ...rest param in Functions and destructuring.md index bcd1356..51df01f 100644 --- a/32 - The ...rest param in Functions and destructuring.md +++ b/32 - The ...rest param in Functions and destructuring.md @@ -1,15 +1,14 @@ -Whenever you see three little dots, it's not just a spread. It could also be what's called a rest param. Even though it looks to be the exact same thing, it's actually the exact opposite thing. Let's think about that for a second. +Whenever you see three little dots, it's not just a spread. It could also be what's called a **rest param**. Even though it looks to be the exact same thing, it's actually the exact opposite thing. Let's think about that for a second. If the **spread** param takes one thing, which is an array, and **unpacks it into multiple items**, or takes a string and unpacks it into multiple items of an array, the **rest** param does the exact opposite. It takes multiple things and **packs it into a single array**. -There's two places where you'll use a rest param. That is first in a function, and second in a destructuring situation. - +There are two places where you'll use a rest param. That is first in a function, and second in a destructuring situation. Let's say we have a function called `convertCurrency`, and it takes two things: a `rate` which is known, but it's also going to take a unknown amount of currency. Here we don't really know how many the person is going to pass. Now you might be saying, "That's fine, don't pass any arguments there, and use the arguments object." The problem here is that we actually want the first thing to be the `rate`, and then the rest of them to be the amounts that the person would like to convert. -Let's say we're going to convert currency, and we want to convert at $1.54 per dollar. Then we want to pass a whole bunch of dollar values that we have. Before now, there wasn't really a great way to do that, but now we have the rest param, which can pack the rest of them into an array: +Let's say we're going to convert currency, and we want to convert at $1.56 per dollar. Then we want to pass a whole bunch of dollar values that we have. Before now, there wasn't really a great way to do that, but now we have the rest param, which can pack the rest of them into an array: ```js function convertCurrecnty(rate, ...amounts){ @@ -47,11 +46,11 @@ We should be able to get an array of all of those converted currency values. You can use as many arguments as you need. If you had `rate`, and `tax`, and `tip`, and then amounts, what that would give us is three things. Let's take a look here: ```js - function convertCurrecnty(rate, tax, tip, ...amounts){ + function convertCurrency(rate, tax, tip, ...amounts){ console.log(rate, tax, tip, amounts); - return amounts.map(amount => amount * rate); + return amounts.map(amount => (amount + amount * tax + amount * tip) * rate); } -const amounts = convertCurrecnty(1.56, 10, 23, 52, 1, 56); +const amounts = convertCurrecnty(1.56, 0.13, 0.15 10, 23, 52, 1, 56); ``` In the console we can see that we get our `rate`, `tax`, and `tip`, and if you open it in your inspector you'll see that it's a true array, not an arguments object, or anything weird and array-ish. It's a true array. @@ -96,4 +95,4 @@ We looked at another example earlier, where we had a team array. The first perso ``` So if we run that, we'll get `Wes`, and `Kait`, and because we used the rest param, we get an array of players, with `Lux`, `Sheena` and `Kelly`. -The rest param might not something you're going to use all the time, but it really helps you when you don't have to do any splicing or counting on indexes. You can just say, "Just give me the rest," for either a function definition, or for when you're destructuring an array. \ No newline at end of file +The rest param might not be something you're going to use all the time, but it really helps you when you don't have to do any splicing or counting on indexes. You can just say, "Just give me the rest," for either a function definition, or for when you're destructuring an array.