One place for hosting & domains

      JavaScript

      How to Use the JavaScript Fetch API to Get Data


      We all remember the dreaded XMLHttpRequest we used back in the day to make requests, it involved some really messy code, it didn’t give us promises and let’s just be honest, it wasn’t pretty JavaScript, right? Maybe if you were using jQuery, you used the cleaner syntax with jQuery.ajax().

      Well JavaScript has it’s own built-in clean way now. Along comes the Fetch API a new standard to make server request jam-packed with promises and all those things we learned to love over the years.

      How do we use the Fetch API?

      In a very simple manner all you really do is call fetch with the URL you want, by default the Fetch API uses the GET method, so a very simple call would be like this:

      fetch(url) // Call the fetch function passing the url of the API as a parameter
      .then(function() {
          // Your code for handling the data you get from the API
      })
      .catch(function() {
          // This is where you run code if the server returns any errors
      });
      

      Looks pretty simple right? So let’s starting using it…

      We are now going to build a simple GET request, in this case, I will use the Random User API and we will get 10 users and show them on the page using vanilla JavaScript.

      Let’s get started with the HTML, all we really need is a heading and an unordered list:

        <h1>Authors</h1>
        <ul id="authors"></ul>
      

      The idea is to get all the data from the Random User API and display it in list items inside the author’s list.

      The first step is to actually set the URL we need and also the list we are gonna put the data in, so in the Javascript we write:

        const ul = document.getElementById('authors'); // Get the list where we will place our authors
        const url="https://randomuser.me/api/?results=10"; // Get 10 random users
      

      I have set these to consts so you don’t risk changing these in the future and these two are meant to be constants through all the project.
      Now we get into actual Fetch API:

      fetch(url)
        .then(function(data) {
          // Here you get the data to modify as you please
          })
        })
        .catch(function(error) {
          // If there is any error you will catch them here
        });   
      

      Let’s review this code, shall we?
      So first we are calling the Fetch API and passing it the URL we defined as a constant above and since no more parameters are set this is a simple GET request.
      Then we get a response but the response we get is not JSON but an object with a series of methods we can use depending on what we want to do with the information, these methods include:

      • clone() – As the method implies this method creates a clone of the response.
      • redirect() – This method creates a new response but with a different URL.
      • arrayBuffer() – In here we return a promise that resolves with an ArrayBuffer.
      • formData() – Also returns a promise but one that resolves with FormData object.
      • blob() – This is one resolves with a Blob.
      • text() – In this case it resolves with a string.
      • json() – Lastly we have the method to that resolves the promise with JSON.

      Looking at all these methods the one we want is the JSON one because we want to handle our data as a JSON object so we add:

        fetch(url)
        .then((resp) => resp.json()) // Transform the data into json
        .then(function(data) {
          // Create and append the li's to the ul
          })
        })
      

      Now let’s get to the part we create the list items, for that, I created two helper functions at the top of my file just to make the code simpler down the line:

        function createNode(element) {
          return document.createElement(element); // Create the type of element you pass in the parameters
        }
      
        function append(parent, el) {
          return parent.appendChild(el); // Append the second parameter(element) to the first one
        }
      

      All these functions do is append and create elements as you can see.
      Once this is done we can move on to the resolution of our promise and add the code we need to append these list items to our unordered list:

      then(function(data) {
          let authors = data.results; // Get the results
          return authors.map(function(author) { // Map through the results and for each run the code below
            let li = createNode('li'), //  Create the elements we need
                img = createNode('img'),
                span = createNode('span');
            img.src = author.picture.medium;  // Add the source of the image to be the src of the img element
            span.innerHTML = `${author.name.first} ${author.name.last}`; // Make the HTML of our span to be the first and last name of our author
            append(li, img); // Append all our elements
            append(li, span);
            append(ul, li);
          })
        })
      

      So first we define authors as the response we get from the request then we map over all the authors and for each we create a list item, a span, and an image.
      In the image source, we place the picture of the user, the HTML of the span will be the first and last name interpolated and then all we need to do is append this to their rightful parents and voilá, our HTTP request in vanilla JavaScript is done and returning something to the HTML.

      To handle our catch all I will do is console log the error as we get it but you can do whatever you want with the error such as append it to the HTML with the functions we created. This is the full code of our little request:

        function createNode(element) {
            return document.createElement(element);
        }
      
        function append(parent, el) {
          return parent.appendChild(el);
        }
      
        const ul = document.getElementById('authors');
        const url="https://randomuser.me/api/?results=10";
        fetch(url)
        .then((resp) => resp.json())
        .then(function(data) {
          let authors = data.results;
          return authors.map(function(author) {
            let li = createNode('li'),
                img = createNode('img'),
                span = createNode('span');
            img.src = author.picture.medium;
            span.innerHTML = `${author.name.first} ${author.name.last}`;
            append(li, img);
            append(li, span);
            append(ul, li);
          })
        })
        .catch(function(error) {
          console.log(error);
        });   
      

      Handling more requests like POST

      So this is a GET request, the default one for the fetch function but of course we can do all other types of requests and also change the headers and off course send data, all we need for this is to set our object and pass it as the second argument of the fetch function:

      const url="https://randomuser.me/api";
      // The data we are going to send in our request
      let data = {
          name: 'Sara'
      }
      // The parameters we are gonna pass to the fetch function
      let fetchData = { 
          method: 'POST', 
          body: data,
          headers: new Headers()
      }
      fetch(url, fetchData)
      .then(function() {
          // Handle response you get from the server
      });
      

      You can also define cache, mode and all those things you are used to defining in your POST requests.

      To create our object and use the fetch function we also have another option and that is to use the request constructor to create our request object, so instead of defining the object in the function itself we do this:

      const url="https://randomuser.me/api";
      // The data we are going to send in our request
      let data = {
          name: 'Sara'
      }
      // Create our request constructor with all the parameters we need
      var request = new Request(url, {
          method: 'POST', 
          body: data, 
          headers: new Headers()
      });
      
      fetch(request)
      .then(function() {
          // Handle response we get from the API
      })
      

      You can use the way you are most comfortable with to build your request object.

      While the Fetch API is not yet supported by all the browsers (currently Safari does not support it) it is the beautiful replacement for XMLHttpRequest we desperately needed in our life.
      There are also polyfills if you really want to use it in more professional projects.



      Source link

      How to Encode and Decode Strings with Base64 in JavaScript


      While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or
      edited it to ensure you have an error-free learning experience. It’s on our list, and we’re working on it!
      You can help us out by using the “report an issue” button at the bottom of the tutorial.

      Encoding and decoding a string in Base64 with JavaScript can be quite handy.

      For that we have the btoa() and atob() functions. These two base64 helper functions are a core part of the HTML spec and available in all modern browsers.

      • btoa() encodes to Base64
      • atob() decodes from Base64
      // Define the string
      var string = 'Hello World!';
      
      // Encode the String
      var encodedString = btoa(string);
      console.log(encodedString); // Outputs: "SGVsbG8gV29ybGQh"
      
      // Decode the String
      var decodedString = atob(encodedString);
      console.log(decodedString); // Outputs: "Hello World!"
      

      Copy and paste the examples above in your Chrome Console to see them working.

      Common use cases for Base64

      • Packaging things like form input and JSON strings into a character set that’s safer to use in HTTP requests
      • Representing binary data in a way that’s compatible with HTML/JavaScript/CSS. – You can embed an image inline in a CSS or JavaScript file using Base64, for example.

      What Base64 is not:

      • It’s in no way meant to be a secure encryption method,
      • It’s not a compression method, encoding a string to Base64 typically results in ~33% longer output.



      Source link

      Understanding Hoisting in JavaScript


      Introduction

      In this tutorial, we’ll investigate how the famed hoisting mechanism occurs in JavaScript. Before we dive in, let’s get to grips with what hoisting is.

      Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution.

      Inevitably, this means that no matter where functions and variables are declared, they are moved to the top of their scope regardless of whether their scope is global or local.

      Of note however, is the fact that the hoisting mechanism only moves the declaration. The assignments are left in place.

      If you’ve ever wondered why you were able to call functions before you wrote them in your code, then read on!

      undefined vs ReferenceError

      Before we begin in earnest, let’s deliberate on a few things.

      console.log(typeof variable); // Output: undefined
      

      This brings us to our first point of note:

      In JavaScript, an undeclared variable is assigned the value undefined at execution and is also of type undefined.

      Our second point is:

      console.log(variable); // Output: ReferenceError: variable is not defined
      

      In JavaScript, a ReferenceError is thrown when trying to access a previously undeclared variable.

      The behaviour of JavaScript when handling variables becomes nuanced because of hoisting. We’ll look at this in depth in subsequent sections.

      Hoisting variables

      The following is the JavaScript lifecycle and indicative of the sequence in which variable declaration and initialisation occurs.

      variable-hoisting

      However, since JavaScript allows us to both declare and initialise our variables simultaneously, this is the most used pattern:

      var a = 100;
      

      It is however important to remember that in the background, JavaScript is religiously declaring then initialising our variables.

      As we mentioned before, all variable and function declarations are hoisted to the top of their scope. I should also add that variable declarations are processed before any code is executed.

      However, in contrast, undeclared variables do not exist until code assigning them is executed.
      Therefore, assigning a value to an undeclared variable implicitly creates it as a global variable when the assignment is executed. This means that, all undeclared variables are global variables.

      To demonstrate this behaviour, have a look at the following:

      function hoist() {
        a = 20;
        var b = 100;
      }
      
      hoist();
      
      console.log(a); 
      /* 
      Accessible as a global variable outside hoist() function
      Output: 20
      */
      
      console.log(b); 
      /*
      Since it was declared, it is confined to the hoist() function scope.
      We can't print it out outside the confines of the hoist() function.
      Output: ReferenceError: b is not defined
      */
      

      Since this is one of the eccentricities of how JavaScript handles variables, it is recommended to always declare variables regardless of whether they are in a function or global scope. This clearly delineates how the interpreter should handle them at run time.

      ES5

      var

      The scope of a variable declared with the keyword var is its current execution context. This is either the enclosing function or for variables declared outside any function, global.
      Let’s look at a few examples to identify what this means:

      global variables

      console.log(hoist); // Output: undefined
      
      var hoist="The variable has been hoisted.";
      
      

      We expected the result of the log to be: ReferenceError: hoist is not defined, but instead, its output is undefined.

      Why has this happened?

      This discovery brings us closer to wrangling our prey.

      JavaScript has hoisted the variable declaration. This is what the code above looks like to the interpreter:

      var hoist;
      
      console.log(hoist); // Output: undefined
      hoist="The variable has been hoisted.";
      

      Because of this, we can use variables before we declare them. However, we have to be careful because the hoisted variable is initialised with a value of undefined.
      The best option would be to declare and initialise our variable before use.

      Function scoped variables

      As we’ve seen above, variables within a global scope are hoisted to the top of the scope. Next, let’s look at how function scoped variables are hoisted.

      function hoist() {
        console.log(message);
        var message="Hoisting is all the rage!"
      }
      
      hoist();
      

      Take an educated guess as to what our output might be.

      If you guessed, undefined you’re right. If you didn’t, worry not, we’ll soon get to the bottom of this.

      This is how the interpreter views the above code:

      function hoist() {
        var message;
        console.log(message);
        message="Hoisting is all the rage!"
      }
      
      hoist(); // Ouput: undefined
      

      The variable declaration, var message whose scope is the function hoist(), is hoisted to the top of the function.

      To avoid this pitfall, we would make sure to declare and initialise the variable before we use it:

      function hoist() {
        var message="Hoisting is all the rage!"
        return (message);
      }
      
      hoist(); // Ouput: Hoisting is all the rage!
      

      Strict Mode

      Thanks to a utility of the es5 version of JavaScript known as strict-mode, we can be more careful about how we declare our variables.
      By enabling strict mode, we opt into a restricted variant of JavaScript that will not tolerate the usage of variables before they are declared.

      Running our code in strict mode:

      1. Eliminates some silent JavaScript errors by changing them to explicit throw errors which will be spit out by the interpreter.
      2. Fixes mistakes that make it difficult for JavaScript engines to perform optimisations.
      3. Prohibits some syntax likely to be defined in future versions of JavaScript.

      We enable strict mode by prefacing our file or function with

      'use strict';
      
      // OR
      "use strict";
      

      Let’s test it out.

      'use strict';
      
      console.log(hoist); // Output: ReferenceError: hoist is not defined
      hoist="Hoisted"; 
      

      We can see that instead of assuming that we missed out on declaring our variable, use strict has stopped us in our tracks by explicitly throwing a Reference error. Try it out without use strict and see what happens.

      Strict mode behaves differently in different browsers however, so it’s advisable to perform feature testing thoroughly before relying on it in production.

      ES6

      ECMAScript 6, ECMAScript 2015 also known as ES6 is the latest version of the ECMAScript standard, as the writing of this article, Jan 2017 and introduces a few changes to es5.

      Of interest to us is how changes in the standard affect the declaration and initialisation of JavaScript variables.

      let

      Before we start, to be noted is the fact that variables declared with the keyword let are block scoped and not function scoped. That’s significant, but it shouldn’t trouble us here. Briefly, however, it just means that the variable’s scope is bound to the block in which it is declared and not the function in which it is declared.

      Let’s start by looking at the let keyword’s behaviour.

      console.log(hoist); // Output: ReferenceError: hoist is not defined ...
      let hoist="The variable has been hoisted.";
      

      Like before, for the var keyword, we expect the output of the log to be undefined. However, since the es6 let doesn’t take kindly on us using undeclared variables, the interpreter explicitly spits out a Reference error.

      This ensures that we always declare our variables first.

      However, we still have to be careful here. An implementation like the following will result in an ouput of undefined instead of a Reference error.

      let hoist;
      
      console.log(hoist); // Output: undefined
      hoist="Hoisted"
      

      Hence, to err on the side of caution, we should declare then assign our variables to a value before using them.

      const

      The const keyword was introduced in es6 to allow immutable variables. That is, variables whose value cannot be modified once assigned.

      With const, just as with let, the variable is hoisted to the top of the block.

      Let’s see what happens if we try to reassign the value attached to a const variable.

      const PI = 3.142;
      
      PI = 22/7; // Let's reassign the value of PI
      
      console.log(PI); // Output: TypeError: Assignment to constant variable.
      

      How does const alter variable declaration? Let’s take a look.

      console.log(hoist); // Output: ReferenceError: hoist is not defined
      const hoist="The variable has been hoisted.";
      

      Much like the let keyword, instead of silently exiting with an undefined, the interpreter saves us by explicitly throwing a Reference error.

      The same occurs when using const within functions.

      function getCircumference(radius) {
        console.log(circumference)
        circumference = PI*radius*2;
        const PI = 22/7;
      }
      
      getCircumference(2) // ReferenceError: circumference is not defined
      

      With const , es6 goes further. The interpreter throws an error if we use a constant before declaring and initialising it.

      Our linter is also quick to inform us of this felony:

      PI was used before it was declared, which is illegal for const variables.
      

      Globally,

      
      const PI;
      console.log(PI); // Ouput: SyntaxError: Missing initializer in const declaration
      PI=3.142;
      

      Therefore, a constant variable must be both declared and initialised before use.


      As a prologue to this section, it’s important to note that indeed, JavaScript hoists variables declared with es6 let and const. The difference in this case is how it initialises them.
      Variables declared with let and const remain uninitialised at the beginning of execution whilst variables declared with var are initialised with a value of undefined.

      Hoisting functions

      JavaScript functions can be loosely classified as the following:

      1. Function declarations
      2. Function expressions

      We’ll investigate how hoisting is affected by both function types.

      Function declarations

      These are of the following form and are hoisted completely to the top. Now, we can understand why JavaScript enable us to invoke a function seemingly before declaring it.

      hoisted(); // Output: "This function has been hoisted."
      
      function hoisted() {
        console.log('This function has been hoisted.');
      };
      

      Function expressions

      Function expressions, however are not hoisted.

      expression(); //Output: "TypeError: expression is not a function
      
      var expression = function() {
        console.log('Will this work?');
      };
      

      Let’s try the combination of a function declaration and expression.

      expression(); // Ouput: TypeError: expression is not a function
      
      var expression = function hoisting() {
        console.log('Will this work?');
      };
      

      As we can see above, the variable declaration var expression is hoisted but it’s assignment to a function is not. Therefore, the intepreter throws a TypeError since it sees expression as a variable and not a function.

      Order of precedence

      It’s important to keep a few things in mind when declaring JavaScript functions and variables.

      1. Variable assignment takes precedence over function declaration
      2. Function declarations take precedence over variable declarations

      Function declarations are hoisted over variable declarations but not over variable assignments.

      Let’s take a look at what implications this behaviour has.

      Variable assignment over function declaration

      var double = 22;
      
      function double(num) {
        return (num*2);
      }
      
      console.log(typeof double); // Output: number
      

      Function declarations over variable declarations

      var double;
      
      function double(num) {
        return (num*2);
      }
      
      console.log(typeof double); // Output: function
      

      Even if we reversed the position of the declarations, the JavaScript interpreter would still consider double a function.

      Hoisting classes

      JavaScript classes too can be loosely classified either as:

      1. Class declarations
      2. Class expressions

      Class declarations

      Much like their function counterparts, JavaScript class declarations are hoisted. However, they remain uninitialised until evaluation.
      This effectively means that you have to declare a class before you can use it.

      
      var Frodo = new Hobbit();
      Frodo.height = 100;
      Frodo.weight = 300;
      console.log(Frodo); // Output: ReferenceError: Hobbit is not defined
      
      class Hobbit {
        constructor(height, weight) {
          this.height = height;
          this.weight = weight;
        }
      }
      

      I’m sure you’ve noticed that instead of getting an undefined we get a Reference error. That evidence lends claim to our position that class declarations are hoisted.

      If you’re paying attention to your linter, it supplies us with a handy tip.

      Hobbit was used before it is declared, which is illegal for class variables
      

      So, as far as class declarations go, to access the class declaration, you have to declare first.

      class Hobbit {
        constructor(height, weight) {
          this.height = height;
          this.weight = weight;
        }
      }
      
      var Frodo = new Hobbit();
      Frodo.height = 100;
      Frodo.weight = 300;
      console.log(Frodo); // Output: { height: 100, weight: 300 }
      

      Class expressions

      Much like their function counterparts, class expressions are not hoisted.

      Here’s an example with the un-named or anonymous variant of the class expression.

      var Square = new Polygon();
      Square.height = 10;
      Square.width = 10;
      console.log(Square); // Output: TypeError: Polygon is not a constructor
      
      var Polygon = class {
        constructor(height, width) {
          this.height = height;
          this.width = width;
        }
      };
      

      Here’s an example with a named class expression.

      var Square = new Polygon();
      Square.height = 10;
      Square.width = 10;
      console.log(Square); // Output: TypeError: Polygon is not a constructor
      
      
      var Polygon = class Polygon {
        constructor(height, width) {
          this.height = height;
          this.width = width;
        }
      };
      
      

      The correct way to do it is like this:

      var Polygon = class Polygon {
        constructor(height, width) {
          this.height = height;
          this.width = width;
        }
      };
      
      var Square = new Polygon();
      Square.height = 10;
      Square.width = 10;
      console.log(Square);
      

      Caveat

      There’s a bit of an argument to be made as to whether Javascript es6 let, const variables and classes are actually hoisted, roughly hoisted or not hoisted. Some argue that they are actually hoisted but uninitialised whilst some argue that they are not hoisted at all.

      Conclusion

      Let’s summarise what we’ve learned so far:

      1. While using es5 var, trying to use undeclared variables will lead to the variable being assigned a value of undefined upon hoisting.
      2. While using es6 let and const, using undeclared variables will lead to a Reference Error because the variable remains uninitialised at execution.

      Therefore,

      1. We should make it a habit to declare and initialise JavaScript variables before use.
      2. Using strict mode in JavaScript es5 can help expose undeclared variables.

      I hope this article will serve as a good introduction to the concept of hoisting in JavaScript and spur your interest regarding the subtleties of the JavaScript language.



      Source link