Unlock FeathersJS power with a todo client

Create a simple to-do client using FeathersJS.

We saw a quick tutorial on creating simple FeathersJS API yesterday. Let’s unlock the full power of Feathers by using its client library and consume the API created in the earlier post!

Install and initialize project

We will use plain Javascript and HTML with Feathers client-side library for the purpose of this demonstration.

Create HTML page

Create a simple HTML page to include -

  • a simple input box to enter new to-do
  • an element to display to-dos fetched from server

We will also include feathers from CDN.

And, copy over styling and scripts from Bootstrap grid and components.

<!-- index.html -->
<!DOCTYPE html>

<html>
  <head>
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type" />
    <meta content="utf-8" http-equiv="encoding" />
    <title>todof!</title>
    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
      integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
      crossorigin="anonymous"
    />
  </head>

  <body>
    <div class="container pt-5">
      <div class="row col-3">
        <h3>Todof Todos!</h3>
      </div>
      <div class="pt-5"></div>
      <div class="row ">
        <div class="input-group col-4">
          <label for="inTodo"></label>
          <input
            type="text"
            class="form-control"
            id="inTodo"
            placeholder="New todo"
          />
        </div>
        <div class="input-group col-1 ">
          <button onclick="insertTodo()">OK</button>
        </div>
      </div>
      <div class="row"></div>
      <div class="pt-5 col-4">
        <div id="todosNode"></div>
      </div>
    </div>
    <script
      src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
      integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
      crossorigin="anonymous"
    ></script>
    <script
      src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
      integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/@feathersjs/client@^4.3.0/dist/feathers.js"></script>

    <script src="app.js"></script>
  </body>
</html>

I bet you noticed that we imported script from app.js. That is the script doing all the magic and let’s start creating that magic.

Initialize and configure feathers

Initialize feathers. Create a socket to establish connection and talk to server.

// app.js
console.log("hello world");

const socket = io();
var client = feathers();
client.configure(feathers.socketio(socket));
Setup authentication

Configure and call authentication service from server to authenticate user.

// app.js
const config = client.get("authentication");

client.configure(feathers.authentication(config));

var token = login();

async function login() {
  const auth = await client.authenticate({
    strategy: "local",
    email: "a@test.com",
    password: "abcde"
  });
  console.log(auth.accessToken);
  return auth.accessToken;
}

We have hard-coded the user id and password for a quick test - typically that should come from a login form.

Just open index.html in a browser and you should be able to see a nice JSON token in the console.

Display to-do’s

Include code to fetch and display to-do’s.

getTodo();

async function getTodo() {
  const todoRecs = await client.service("todo").find();
  this.renderList("todosNode", todoRecs);
}

async function renderList(nodeId, data) {
  document.getElementById(nodeId).innerHTML = "";
  let dataList = "";
  for (var i = 0; i < data.data.length; i++) {
    dataList += "<li>" + data.data[i]["title"] + "</li>";
  }
  document.getElementById(nodeId).innerHTML = `<ul>${dataList}</ul>`;
}
Create to-do

Tie the input box to the flow. Create new to-do when ‘OK’ is clicked.

async function insertTodo() {
  console.log("todo is ", document.getElementById("inTodo").value);
  const todoCreate = await client
    .service("todo")
    .create({ title: document.getElementById("inTodo").value });
  console.log("todo created");
  document.getElementById("inTodo").value = "";
  this.getTodo();
}

End result

Without writing a lot of code, we have -

  1. Created a HTML page that talks to our back-end Feathers server
  2. Fetched to-dos and displayed them on the UI
  3. Insert a to-do record without much fuss

feathersjs-simple-todo-demo

Full code

Find all code on GitHub. Here’s the full Javascript in app.js.

// app.js
console.log("hello world");

const socket = io();

var client = feathers();
const config = client.get("authentication");

client.configure(feathers.socketio(socket));
client.configure(feathers.authentication(config));

var token = login();

getTodo();

async function login() {
  const auth = await client.authenticate({
    strategy: "local",
    email: "a@test.com",
    password: "abcde"
  });
  return auth.accessToken;
}

async function getTodo() {
  const todoRecs = await client.service("todo").find();
  this.renderList("todosNode", todoRecs);
}

async function renderList(nodeId, data) {
  document.getElementById(nodeId).innerHTML = "";
  let dataList = "";
  for (var i = 0; i < data.data.length; i++) {
    dataList += "<li>" + data.data[i]["title"] + "</li>";
  }
  document.getElementById(nodeId).innerHTML = `<ul>${dataList}</ul>`;
}

async function insertTodo() {
  console.log("todo is ", document.getElementById("inTodo").value);
  const todoCreate = await client
    .service("todo")
    .create({ title: document.getElementById("inTodo").value });
  console.log("todo created");
  document.getElementById("inTodo").value = "";
  this.getTodo();
}
comments powered by Disqus