GUIPSS

👉 Articles tagged : javascript

Use Vue-i18n in Vuex store

Posted on: 2018-08-24
Categories: javascript - vue

Here is a good way to configure Vue-i18n so you can use it in your Vuex Store

First, create a file just to configure the internationnalization, we can name it i18n.js, at the root of our project.

import Vue from 'vue';
import VueI18n from 'vue-i18n';
import moment from 'moment';

Vue.use(VueI18n);

// if you are using moment in your project, now is a good time
// to set its locale also
moment.locale(locale);

const i18n = new VueI18n({
  locale, // global variable holding the local value
  messages, // globale variable holding translations
});

export default i18n;

The in your main.js file :


import i18n from './i18n';

// ...

new Vue({
  i18n,
  el: `#app`,
  router,
  components: { App },
  template: ``,
  store,
});

And in your Vuex Store (I am using vue-toasted to display messages in a toaster) :

import axios from 'axios';
import Vue from 'vue';
import moment from 'moment';
import i18n from '../../i18n';

export default {
  state : {
    // ...
  },
  mutations : {
    // ...
  },
  actions : {
    doSomething ({ dispatch }, data) {
      return axios.post(`/api/something`, data)
      .then(res => {
        Vue.toasted.success(i18n.tc(`store.success_doing_something`));
      })
      .catch(() => {
        Vue.toasted.error(i18n.tc(`store.error_while_doing_something`));
        return Promise.reject();
      });
    },
  },
};


Simple and automatic HTTPS proxy with Greenlock, LetsEncrypt and node-http-proxy

Posted on: 2018-08-21
Categories: javascript - es6

Thanks to greenlock and node-http-proxy, creating a https proxy whith Let's Encrypt has never been easier. Basically, we just have to mix the two :

var Greenlock = require('greenlock');
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer({});
var redir = require('redirect-https')();

// let's create ou greenlock server first

var greenlock = Greenlock.create({
  // check greenlock's doc for the entire code sample
});


require('http').createServer(greenlock.middleware(redir)).listen(80);

require('https').createServer(greenlock.tlsOptions, function (req, res) {
  // proxy request instead of serving content :
  return proxy.web(req, res, {
    target: 'https://another-server.com',
  });
}).listen(443);

😉


Docker : log multiple containers at once

Posted on: 2018-05-12

If you are working on a project and you chose to use a microservices architecture where every service run in a docker container, you might want to keep an eye on every container logs as you work on them. But attaching every container to a terminal can become a little messy as your number of microservices increases.

I wanted to create all my container detached (-d options of docker run) and have all the logs of all my containers in one terminal. So I made a little CLI tool that does just that :

npm install -g docklog

Then :

docklog -f my-container1 my-container2 ...

The -f option is the same than docker container log, it will "stream" the log to your console as they are being updated.


Vue.js : Pass all props to child components

Posted on: 2018-04-21

Passing all props from a component to a child component in Vue is generally considered not a good thing to do... but you might want to do it anyway because you know what you are doing 😉 I'll try to write a post on how to avoid such a pattern later, but here it is :

Let's say you are using a framework that provide you with a component named VMenu, and you want to wrap that component in your own component (MyMenu) and pass all the props :

export default {
  name : `MyMenu`,
  functional : true,
  render (createElement, context) {
    return createElement(`div`, {}, [
      createElement(`v-menu`, {
        props : {
          ...context.props,
          aPropYouWantToOverride : `value`,
        },
      }, [
        context.slots().default, //  also pass default slot to child
        createElement(`template`, { slot : `activator` }, context.slots().activator), // passing another named slot (named "activator")
      ]),
    ]);
  },
};

The important thing here is to create a functionnal component, because that will automatically take all the props given to our MyMenu component and put them in the context object.


Wait for a function if it returns a promise (but you're not sure it does)

Posted on: 2018-02-17
Categories: javascript - es6

If you are working on an npm module, a library or a plugin system, there is times where might want to call a function without being sur it returns a promise or not. Here is an example that may help you achieve what you want :

const returnsAPromise = () => Promise.resolve();
const returnsARejectedPromise = () => Promise.reject(`Error !`);
const returnsOne = () => 1;

const asyncFunction = async (unknwnFunction) => {

  await returnsAPromise();
  // obvioulsy that passes

  try { await returnsARejectedPromise() }
  catch (e) {
    // obviously that fails...
    console.log(`Of course that failed :`, e);
  }

  // now...
  const one = await returnsOne();
  // thats fine and one === 1
  console.log(`I waited a regular function, one = ${one}`);

  // So it means that if we dont know if a function returns a promise
  // or just a value
  // we can just
  const result = await unknwnFunction();
  // it is usefull when you are, for example,
  // programmig an npm module and the function you call is
  // provided by the user
  console.log(`unknownFunction returned (wrapped in a promise or not): ${result}`);

};

const regularFunction = (unknwnFunction) => {

  // if we are not in a async function, we can also do :
  return Promise.resolve(unknwnFunction())
  .then(result => {
    console.log(`whatever unknownFunction returned : `, result);
  })
  .then(() => {
    // and yes, it would work even if the function fails :
    return Promise.resolve(returnsARejectedPromise());
  })
  .catch(err => {
    // this code is executed
    console.error(`It failed :`, err);
  });

};

asyncFunction(() => `Hi there !`)
.then(() => regularFunction(() => `Hello ladies !`))


Progressive web app: check service worker update

Posted on: 2017-08-06
Categories: pwa - javascript

If you stumble on this article it probably means that you are learning how service workers work. If it's the case, I recommend you to start with this great introduction on MDN.

Though you can write your own service worker, I advise you to start with somethng easier like sw-precache, wich is a great librairy that generate a service worker file directly from your static assets list. 😙

Anyway, let's get to what this article is about: manualy check for an update of our service worker.

As you might have read on the MDN guide linked above, the navigator will check for an update of your service worker every 24h or so. But in some case, you may want to check more often, or even provide a way for your users to check for update from your webapp.

If you use sw-precache or have written your own service worker, you've already registered it like this. Instead of the console.log in this file, we can write some code to alert our user that un udpate is available and that they should refresh the page. The most simple thing would be this one line of code :

document.getElementById("app-wrapper").className = "update-available";

With some css, it would be easy to show the "update available" message on the page.

Then what you should do to check manualy for an update is this :

if (`serviceWorker` in navigator) {
  return navigator.serviceWorker.getRegistration()
    .then(registration => {
      if (!registration) { return null; }

      return registration.update();
    });
}

This will get the current service worker registration and tell the navigator to check for an updgrade. Then the event you catch in your service worker registration file (installingWorker.onstatechange) will take be triggered and tell your user to refresh the page ! 😉


⚡️ Vuex module + Firebase auth

Posted on: 2017-07-30
Categories: vue - javascript

Most of the time, it might be best not to use vuew with firebase. But some times you need to, or you just want to use the authentication part. Here is a way to implement firebase authentication via a Vuex module:


import firebase from 'firebase/app';
import 'firebase/database';
import 'firebase/auth';

const FBConfig = {
  // your firebase credentials...
};
firebase.initializeApp(FBConfig);

const firebaseModule = {
  state: {
    user: null,
    error: '',
    initialized: false,
  },
  mutations: {
    SET_USER(state, user) {
      state.user = user;
    },
  },
  actions: {
    init({ commit, state }) {
      if (state.initialized) {
        return;
      }
      state.initialized = true;

      firebase.auth().onAuthStateChanged(function (user) {
        if (user) {
          console.log(user);
          commit('SET_USER', user);
        } else {
          commit('SET_USER', null);
        }
      });
    },
    login({ state, dispatch }, credentials) {
      return dispatch('init')
        .then(() => firebase.auth().signInWithEmailAndPassword(credentials.email, credentials.password))
        .then((res) => {
          console.log(res);
        })
        .catch(function (error) {
          console.log(error);
          state.error = error;
        });
    },
    signup({ state, dispatch }, credentials) {
      return dispatch('init')
      .then(() => firebase.auth().createUserWithEmailAndPassword(credentials.email, credentials.password))
      .then((res) => {
        console.log(res);
      })
      .catch(function (error) {
        console.log(error);
        state.error = error;
      });
    },
  },
};

export default firebaseModule;

Express-session and the redirect() function

Posted on: 2017-06-25

If you are using express-session in your express app, you might have wanted to use the res.redirect() function, and you may have faced an unexpected behaviour : changes on session data are not always saved when the client receives the redirect response from the server and makes a new request to the server.

Here is a solution to always save the session before sending a redirect response : create a middleware that overide the redirect function.

app.use((req, res, next) => {
  const oldRedirect = res.redirect;
  res.redirect = function (...args) {
    if (req.session) {
      // redirecting after saving...
      req.session.save(() => Reflect.apply(oldRedirect, this, args))
    } else {
      Reflect.apply(oldRedirect, this, args);
    }
  }
})

As you can see ES6 make it simpler ! 😗


😎 Cool code : async function always return a promise

Posted on: 2017-05-13
Categories: javascript - es6

There is really just two things to know to understand javascript async/await :

  • an async function return a promise
  • await always wait for a promise to be resolved and gives you the value it resolved with (so it raises an error if the promise was rejected)
'use strict';

const myAsyncFunc = async function () {
  await Promise.resolve();
  console.log(`In myAsyncFunc`);
}

const failFunc = async function () {
  await Promise.reject();
  console.log(`In failFunc`);//wont be executed
}

myAsyncFunc()
.then(() => {
  console.log(`After myAsyncFunc`);
})
.then(failFunc)
.catch(err => {
  console.log(`Catch error in failFunc`);
})
}

Result :

In myAsyncFunc
After myAsyncFunc
Catch error in failFunc

Of course we can also resolve promises with try/catch ! 😉


Express JS error handling 🌩

Posted on: 2017-05-08

One of the first difficulties you can encounter when you start using Express, is how to handle errors well, especialy if you're using promises.

Here is one way to go. To understand it, remember that in Express, call the next function with an argument (next(new Error('Details about my error')) for example). When you do this, the next middleware capale of handling that argument will be used.

const express = require(`express`);
const app = express();

app.use(`/`, (req, res, next) => {
  return Promise.reject(`something went wrong`)
  .then(() => {
    // of course this wont happen
    // ...
  })
  .catch(next);
})

app.use((req, res, next) => {
  // this middleware won't be called
  res.send(`Everything is fine`);
})

app.use((err, req, res, next) => {
  console.log(err);
  res.status(500).send(`Your request could not be processed`);
})

app.listen(3000, () => {
  console.log(`Example app listening on port 3000!`);
})

Browsing http://localhost:3000/, we'll just see the message : Your request could not be processed.


Cool code : concurrent async calls

Posted on: 2017-04-26
Categories: javascript - es6
var myAsyncFunc = async function () {
  const [ a, b ] = await Promise.all([ promiseFunc1(), promiseFunc2() ]);
  // the two calls are made at the same time, and we get back two variable
  // that can be used right away :
  console.log(a);
  console.log(b);
}


Migrations examples with node-db-migrate

Posted on: 2017-01-02

Create / Remove Table


exports.up = db =>
  db.createTable(`book`, {
    columns : {
      id : {
        type       : `text`,
        primaryKey : true,
      },
      title : {
        type: `text`,
      },
      createdAt : {
        type : `datetime`,
      },
      updatedAt : {
        type : `datetime`,
      },
    },
  })
;

exports.down = db =>
  db.dropTable(`book`)
;

Add Column / Remove Column


exports.up = db =>
  db.addColumn(`user`, `node`, { type : `text` })
;

exports.down = db =>
  db.removeColumn(`user`, `node`)
;