Ryan Evans
Flatiron School Blog


Ruby | Rails | SQLite | React | Redux | JavaScript | HTML | CSS

JavaScript Function Scope

When learning JavaScript, scope can be confusing to understand. Without understanding scope, you can experience unexpected behavior in your code.

Take a look at the following code snippet. What do you think will be logged to the console?

let word = ‘outside';
function logWord(){
    console.log(word);
    let word = ‘inside';
};
logWord();


I’ll give you a hint: it won’t log ‘outside’. It won’t log ‘inside’. And guess what, it won’t throw an error.
What’s the answer? It will log ‘undefiined’ to the console. This is because of functions create their own, or a new, scope.

let word = ‘outside’;
// global scope
function logWord(){
    // new scope starts here, so variables declared inside won’t be available outside the function
    console.log(word);
    let word = ‘inside';
};


To understand this better, we should go over declaration vs. assignment.



Declaration vs. Assignment

Declaration is simply that, declaring that a variable exists. This does not include the assignment of its value. It only initializes the variable and by default sets its value to ‘undefined’.

let word
// word is assigned a value of 'undefined' by default


We could also declare the variable and assign its value at the same time:

let word = ‘outside’


In JavaScript, variable declarations are hoisted to the top of their scope, but their assignments are not, so their values are set to ‘undefined’ by default.
Let’s rewrite our code to reflect the way it is read:

let word = ‘outside’;
function logWord(){
    let word  // word is declared and assigned a value of ‘undefined'
    console.log(word);
    word = ‘inside’;  // word is assigned a value of ‘inside’
};



So when we hit the console.log() line in our function, the value of word is ‘undefined’, until the next line in the function which assigns the value of word to ‘inside’. Therefore, the console statement will log ‘undefined’.

The best way to avoid unexpected behavior in your code is to declare your variables at the top of their scope.


Event Delegation in JavaScript

Event delegation allows attaching an event listener to a parent node/element, rather than directly to the element itself.

To understand event delegation, we first need to know what event bubbling is. Event bubbling is the process where an event (a mouse click, for example) “bubbles” up through all its parent elements, or nodes. This is also event propagation, when the event (click) propagates up the DOM, and can be “heard” by all its parent elements. You can “listen” for the event by setting an event listener. An event listener is when we listen for actions that happen on an elements, in order to then execute a function. The event itself contains information about what happened (like what element/node was clicked).
For example:
``` const parentNode = document.getElementByID(“parentIdName”) parentNode.addEventListener( “click”, () => { doSomething(event) } )


Progressive Web Apps

What makes a web app, a Progressive Web App?

“Progressive Web Apps provide an installable, app-like experience on desktop and mobile that are built and delivered directly via the web. They’re web apps that are fast and reliable. And most importantly, they’re web apps that work in any browser.” - Google Codelabs

Progressive Web Apps have specific attributes:

  • Fast - it should load visible content to the page quickly, as quickly as if you were opening a native app on your device.
  • Reliable - it shouldn’t vary in load time or responsiveness.
  • Responsive - it should work on both mobile and desktop platforms with a single codebase (so if you’re considering building a native application, you should strongly consider building a PWA instead).
  • Installable - a user should have the option to install the app, without using an app store, and have the same user experience as an installed app, regardless of network connection.

Common Error When Calling Dispatch Actions in Redux

I recently met with a senior developer and we got on the topic of calling dispatch actions in Redux.

He said that, even for developers with more experience, it’s a frequent mistake to forget to call a dispatch action correctly by appending this.props to the function call. So simple, but apparently he sees it actually happen pretty often.

So, instead of a correct call like this inside a container (or ‘smart’) component:
this.props.getFetchedData()

Your call will look like this:
getFetchedData()

The way you’ll know that you’ve made this mistake is when it appears that your dispatch action just doesn’t execute ( possibly without any generated error). If you console.log() at different points inside your function, you’ll see that the action function will be called and will execute, but it stops executing at the line that contains the dispatch .
I’ve had this happen to me without any error to give me a hint at my mistake. It simply stopped executing when it hit the dispatch() . It was strange.


Remember that when you mapDispatchToProps() , or use the connect() helper function from react-redux, you’ve made your dispatch actions available as props, and therefore have to call them appropriately. Otherwise, you’re calling it as just a function, because you imported it into your component.

So hopefully if you understand why it happens, you’ll be more likely to remember the fix if (or when, apparently) it happens to you.

Here are some additional reading resources on the subject:


The Geolocation API

The Geolocation API allows the user to provide their location to an application if they wish to. The Geolocation API is provided through the navigator.geolocation object. If the navigator.geolocation object exists, then Geolocation services are available. Here’s a simple example to test if geolocation services are available, provided by MDN:

if ("geolocation" in navigator) {
  /* geolocation is available */
} else {
  /* geolocation IS NOT available */
}