Build A Simple ToDo App using Svelte and Cosmic JS

Build A Simple ToDo App using Svelte and Cosmic JS

Build A Simple ToDo App using Svelte and Cosmic JS - In this tutorial, I'm going to show you how to create a simple Todo application using Svelte, and Cosmic JS. So lets grab a cup of coffee and start coding.

Originally published by Sumit Kharche at medium.com

TL;DR

Prerequisites

You need to have installed the latest stable version of Node JS and NPM. You will have no problem following the tutorial if you have a basic understanding of:

  • HTML, CSS, and JavaScript
  • import and export syntax (ES6 modules)
  • async/await syntax
  • concepts like components
  • the axios API

Let's get started with our technology stack.

What is Svelte?

Svelte is a JavaScript UI library created by Rich Harris. Couple of months ago Svelte 3 has been released. So you think that why we need to learn Svelte if we have React/Angular/Vue. Aren't these language/frameworks enough? There is great article published in Svelte which gives you the reason behind developing the Svelte. Here is link : svelte-3-rethinking-reactivity

So below are some interesting points about Svelte:

  • Svelte is a compiler, not a dependency like React or Vue
  • Svelte seems to need less code for the same things that with React require 40% more LOC (source: Rich Harris)
  • Svelte has no virtual DOM, compiles to minimal “vanilla” JavaScript and seems more performing than other libraries
  • Your app is tremendously faster. If you see this JS Framework Benchmark, Svelte is very much faster than the apps built using Angular, React, Vue, etc. This is because Svelte is nothing but vanilla JS.

If you want to learn more about the Svelte, go through Svelte REPL.

What about Cosmic JS?

Cosmic JS is an API-first CMS that helps teams of developers and content editors build apps faster. It provides lots of great features which will help to easily manage data. Cosmic JS is an amazing content management system with options to categorize and distribute data in a way that makes sense to you.

Create new bucket in Cosmic JS

To create app we will require fetch or store data. For this we will be using the power of Cosmic JS. Create a free account on Cosmic JS and create new empty bucket & name it as todo-app. For basic Todo list app will have two object types:

  • Name
  • IsCompleted

So add this property in bucket along with some initial data. Follow this steps to create bucket in Cosmic JS.

Create Svelte application

It is very easy to create Svelte app. We are using default template for creating the Todo list application.

npx degit sveltejs/template todo-app
cd todo-app
npm install

To run it on local machine hit below command.

npm run dev

By default Svelte app is run on localhost:5000.

So you can see the rollup.config.js file in the project. Like webpack, rollup.js is module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application.

The starting point of Svelte app is the main.js file. All the Svelte component has .svelte extension. If you take look around the files you will see the App.svelte file which is root component. So a basic Svelte component is divided into 3 parts:

  • Under script tag you have to write your JavaScript code.
  • Under style tag you have to define you style. It uses CSS-in-JS style to define you CSS.
  • Then you can the write HTML markup.

Now first we are fetching the Todos from Cosmic JS using the Cosmic JS Rest api. So to connect you application with Cosmic JS Bucket create the config.js file inside src folder and below code.

export default {
    bucket: {
        slug: 'COSMIC_BUCKET',
        read_key: 'COSMIC_READ_KEY',
        write_key: 'COSMIC_WRITE_KEY',
        port: 'PORT',  
      }
  }

To replace the variable defined in config.js file during the build time we have to install a new plugin called rollup-plugin-replace. After installation open the rollup.config.js file and replace the below code.

import svelte from 'rollup-plugin-svelte';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
import replace from 'rollup-plugin-replace';

const production = !process.env.ROLLUP_WATCH;

export default { input: 'src/main.js', output: { sourcemap: true, format: 'iife', name: 'app', file: 'public/bundle.js' }, plugins: [ svelte({ // enable run-time checks when not in production dev: !production, // we'll extract any component CSS out into // a separate file — better for performance css: css => { css.write('public/bundle.css'); } }),

    // If you have external dependencies installed from
    // npm, you'll most likely need these plugins. In
    // some cases you'll need additional configuration —
    // consult the documentation for details:
    // https://github.com/rollup/rollup-plugin-commonjs
    resolve({ browser: true }),
    replace({
        COSMIC_BUCKET: process.env.COSMIC_BUCKET || 'b8342310-9b59-11e9-8ad5-5f72f4c21499',
        COSMIC_READ_KEY: process.env.COSMIC_READ_KEY || '',
        COSMIC_WRITE_KEY: process.env.COSMIC_WRITE_KEY || '',
        PORT: process.env.PORT || ''
      }),
    commonjs(),

    // Watch the `public` directory and refresh the
    // browser on changes when not in production
    !production && livereload('public'),

    // If we're building for production (npm run build
    // instead of npm run dev), minify
    production && terser()
],
watch: {
    clearScreen: false
}

};

So we have completed the Cosmic JS integration with our Svelte app. First we are going to fetch the Todos from Cosmic JS Bucket. Here we are using App,svelte as our container component. Like any other libraries Svelte has also its own lifecycle methods i.e. OnMount, beforeUpdate, afterUpdate, onDestroy,etc.

We need to fetch data every time App.svelte component mounts. Fetching data from Cosmic JS Rest endpoint we will be using axios. So first install axios.

npm install axios

After that for each todo create new component called TodoItem.svelte. This component is used to display single todo. So loop over each todo and send it as props to TodoItem.svelte component. On Svelte site there is good collection of examples. You can see here.

As Svelte has CSS-in-JS we can define CSS for each component. After fetching, we have to add the new todo. For doing this create input field and button in App,svelte file and on click of button call post api to add new todo in Cosmic Js database. Same changes are require for updating the IsComplete flag and delete todo.

Update index.html file to add Bootstrap and font-awesome:

<!doctype html>
    <html>
    <head>
        <meta charset='utf8'>
        <meta name='viewport' content='width=device-width'>

    &lt;title&gt;Svelte &amp; Cosmic JS App&lt;/title&gt;


    &lt;link rel='icon' type='image/png' href='/favicon.png'&gt;
    &lt;link rel='stylesheet' href='/global.css'&gt;
    &lt;link rel='stylesheet' href='/bundle.css'&gt;
    &lt;link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous"&gt;
    &lt;link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"&gt;


&lt;/head&gt;


&lt;body&gt;
    &lt;script src='/bundle.js'&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

See the below complete code for this simple Todo list application:

<script>
  import { onMount } from "svelte";
  import axios from "axios";
  import config from "./config.js";
  import TodoItem from "./TodoItem.svelte";
  export let name;
  let todo = "";
  $: todos = [];
  onMount(getTodos());
  function getTodos() {
    axios
      .get(
        https://api.cosmicjs.com/v1/${           config.bucket.slug         }/object-type/todos?sort=created_at
      )
      .then(response => {
        todos = response.data.objects;
      });
  }
  function handleAddTodo() {
    axios
      .post(https://api.cosmicjs.com/v1/${config.bucket.slug}/add-object, {
        type_slug: "todos",
        title: todo,
        content: "New Task",
        metafields: [
          {
            title: "Is Complete",
            key: "is_complete",
            value: false,
            type: "text"
          }
        ]
      })
      .then(response => {
        if (response.data) {
          todos = [...todos, response.data.object];
        }
      });
    todo = "";
  }
  function handleComplete(event) {
    const todo = event.detail.todo;
    axios
      .put(https://api.cosmicjs.com/v1/${config.bucket.slug}/edit-object, {
        slug: todo.slug,
        metafields: [
          {
            title: "Is Complete",
            key: "is_complete",
            value: !todo.metadata.is_complete,
            type: "text"
          }
        ]
      })
      .then(response => {
        if (response.data) {
          getTodos();
        }
      });
  }
  function handleDelete(event) {
    const todo = event.detail.todo;
    axios
      .delete(https://api.cosmicjs.com/v1/${config.bucket.slug}/${todo.slug})
      .then(response => {
        if (response) {
          getTodos();
        }
      });
  }
</script>

<style> h2 { color: white; } .jumbotron { background-color: cornflowerblue; }

.footer { position: fixed; left: 0; bottom: 0; padding: 40px; width: 100%; color: black; text-align: center; } .footer-logo { width: 25px; height: 25px; } a { text-decoration: none; color: #108db8; font-weight: bold; } img { max-width: 100%; } </style>

<div> <div class="jumbotron" style="padding:45px 0px"> <h2 class="text-center">Svelte & Cosmic JS App</h2> </div> </div> <div class="container"> <div class="row"> <div class="col-md-6 offset-md-3">

  &lt;div class="input-group"&gt;
    &lt;input
      bind:value={todo}
      class="form-control"
      placeholder="Enter todo" /&gt;
    &lt;div class="input-group-addon hover-cursor" on:click={handleAddTodo}&gt;
      &lt;i class="fa fa-plus-circle fa-2x" /&gt;
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;div style="margin:5px 0px"&gt;
    &lt;ul class="list-group"&gt;
      {#each todos as todo}
        &lt;TodoItem
          {todo}
          on:deleteTodo={handleDelete}
          on:toggleComplete={handleComplete} /&gt;
      {/each}
    &lt;/ul&gt;
  &lt;/div&gt;
&lt;/div&gt;

</div> </div>

Here is the TodoItem.svelte component:

<script>
    import { createEventDispatcher } from 'svelte';
    export let todo;
    const dispatch = createEventDispatcher();
    function deleteTodo() {
        dispatch('deleteTodo', {
            todo: todo
        });
    }
    function toggleComplete() {
        dispatch('toggleComplete', {
            todo: todo
        });
    }
</script>

<style> .completed { text-decoration: line-through; color: grey; } .text-success { color:green; } .hover-cursor{ cursor: pointer; } </style>

<li class="list-group-item"> <span class="hover-cursor {todo.metadata.is_complete ?'text-success':''}" on:click={toggleComplete}> <i class="fa fa-lg {todo.metadata.is_complete ?'fa-check-circle-o':'fa-circle-thin'}"></i> </span> {todo.title} <span class="hover-cursor text-danger pull-right" on:click={deleteTodo}> <i class="fa fa-trash-o fa-lg"></i> </span> </li>

So now run the below command to see the amazing Todo list application.

$ npm run dev

Open localhost:5000.

To build application in production mode you just need to run

$ npm run build

To test the production build before publishing, run below command

$ npm run start

Deploy it

We can now deploy our application on any hosting platform. I recommend deploying it on Netlify because it supports project structures like this and can quickly create deployments. You can deploy application on Now or Surge also.

Conclusion

In this article I have demonstrated you how to create a Todo application using Svelte and Cosmic JS. The Cosmic JS Community has a lot of examples on how to handle integration with email functions, download functions, and third party platforms.

I really hope that you enjoyed this little app, and please do not hesitate to send me your thoughts or comments about what could I have done better.

Originally published by Sumit Kharche at medium.com

===========================================

Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

Learn More

☞ Svelte.js - The Complete Guide

☞ The Complete JavaScript Course 2019: Build Real Projects!

☞ Become a JavaScript developer - Learn (React, Node,Angular)

☞ JavaScript: Understanding the Weird Parts

☞ JavaScript: Coding Challenges Bootcamp - 2019

☞ The Complete Node.js Developer Course (3rd Edition)

☞ Angular & NodeJS - The MEAN Stack Guide

☞ NodeJS - The Complete Guide (incl. MVC, REST APIs, GraphQL)

☞ Node.js Absolute Beginners Guide - Learn Node From Scratch

javascript web-development

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Hire Web Developer

Looking for an attractive & user-friendly web developer? HourlyDeveloper.io, a leading web, and mobile app development company, offers web developers for hire through flexible engagement models. You can **[Hire Web...

Why Web Development is Important for your Business

With the rapid development in technology, the old ways to do business have changed completely. A lot more advanced and developed ways are ...

Important Reasons to Hire a Professional Web Development Company

    You name the business and I will tell you how web development can help you promote your business. If it is a startup or you seeking some...

Hire Dedicated eCommerce Web Developers | Top eCommerce Web Designers

Build your eCommerce project by hiring our expert eCommerce Website developers. Our Dedicated Web Designers develop powerful & robust website in a short span of time.

How long does it take to develop/build an app?

This article covers A-Z about the mobile and web app development process and answers your question on how long does it take to develop/build an app.