SHARE
Facebook X Pinterest WhatsApp

Working with Services in JavaScript

thumbnail Working with Services in JavaScript
Written By
thumbnail Diogo Souza
Diogo Souza
Jan 28, 2019

JavaScript is a multi-paradigm language. You can “emulate” various programming techniques with it, and this is incredible because we can decide the best paradigm for solving the problems of our projects.

But if, on the one hand, this gives a great power to the language, it can also leave beginners confused. It is very common to choose the wrong approach for a problem.

Thinking about it many developers create their own solutions, some thinking of helping others in enforcing standards.

Encapsulating Logics

Everything in JavaScript is an object (except undefined), so services are also objects. This way, mastering how we create and work with objects is much simpler.

Scope and Closures

JavaScript has a lexical scope. Among other things, this allows you to create closures. In a nutshell, you create a “controlled environment” where there are functions/variables that can only be accessed in that scope, creating the closure.

const initPage = (root) => {
    const $root = $(root);
    const $menu = $root.find('.menu');
    const $profile = $menu.find('.profile');

    const initProfile = () => {
        $.get('/me')
            .then(response => {
                $profile.text(response.username);
            });
        //  ...
    };

    const showProfileModal = e => {
        // ...
    };

    $profile.on('click', e => showProfileModal(e));

    initProfile();
};

This is a simple example, but it illustrates just how well we created closures. Variables declared inside initPage only exist in that scope.

In the same example we can refactor this code in an Immediately-Invoked Function Expression (IIFE).

((root) => {
  const $root = $(root);
  const $menu = $root.find('.menu');
  const $profile = $menu.find('.profile');

  const initProfile = () => {
    $.get('/me')
     .then(response => {
       $profile.text(response.username);
     });
    //  ...
  };

  const showProfileModal = e => {
    // ...
  };

  $profile.on('click', e => showProfileModal(e));

  initProfile();
})('body');

In this code, we declare a function and execute it immediately, passing an argument. This is extremely useful when we want to perform processing of information that will only serve to create a variable.

const timezones = (() => {
  const zones = [];
  const min = -12;
  const max = 13;
  let simbol;

  for (let i = min; i <= max; i++) {
    simbol = (i < 0) ? '' : '+';
    zones.push(`GMT${simbol}${i}`);
  }

  return zones;
})();

As you may already have realized, you can expose data from a closure as in the previous example. The “zones” variable is returned, so the “timezones” variable now has the closure result as its value.

In this example, the closure does not use external data (parent scope), but given the JavaScript nature… this is perfectly possible.

This is useful to not pollute the main scope with irrelevant information.

const makeCounter = (start = 0) => {
  let current = start;

  const add = (value = 1) => current += value;
  const remove = (value = 1) => add(value * -1);
  const get = () => current;

  return { add, remove, get };
};

const counter = makeCounter(10);

counter.add() // 11
counter.add() // 12
counter.add(8) // 20
counter.remove(10) // 10

In this example, we are combing closures with factory. With this, we can create several counters, and work as best as we can with them.

If you understand how the counter example works, congratulations you already know how to create services with JavaScript. That’s right, this counter is a service. In fact it is a “factory,” but with small adjustments it becomes a service that is easy to reuse.

To reinforce, I will leave another example of use of services:

import Http from './http.js';
import UsersService from './modules/users/service.js';

Http.setToken('XPTO'); // Define o token de autentificação

// Cattega a primeira página de usuários
// Exibe um alerta com o nome do primeiro usuário retornado pelo serviço

UsersService
  .getAll({ page: 1 })
  .then(result => result.data)
  .then(data => data[0])
  .then(first => {
    alert(first.name);
  });

The Http service is also used by the users service, so it is possible to set the authentication token before actually using the services because they will share the same status/service.

Another interesting feature is that these services are not directly linked to any context. This means that no matter what environment you are in or what framework you are using, the services are agnostic. They can be used in Node.JS, Vue.JS, React.JS, etc.

This is one of the principles of JavaScript Polymorphisms … however this is a subject for another day.

About the Author

Diogo Souza works as a Java Developer at PagSeguro and has worked for companies such as Indra Company, Atlantic Institute and Ebix LA. He is also an Android trainer, speaker at events on Java and mobile world.

Recommended for you...

The Revolutionary ES6 Rest and Spread Operators
Rob Gravelle
Aug 23, 2022
Ahead of Time (AOT) Compilation in Angular
Tariq Siddiqui
Aug 16, 2022
Converting a JavaScript Object to a String
Rob Gravelle
Aug 14, 2022
Understanding Primitive Type Coercion in JavaScript
Rob Gravelle
Jul 28, 2022
HTML Goodies Logo

The original home of HTML tutorials. HTMLGoodies is a website dedicated to publishing tutorials that cover every aspect of being a web developer. We cover programming and web development tutorials on languages and technologies such as HTML, JavaScript, and CSS. In addition, our articles cover web frameworks like Angular and React.JS, as well as popular Content Management Systems (CMS) that include WordPress, Drupal, and Joomla. Website development platforms like Shopify, Squarespace, and Wix are also featured. Topics related to solid web design and Internet Marketing also find a home on HTMLGoodies, as we discuss UX/UI Design, Search Engine Optimization (SEO), and web dev best practices.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.