Book Image

Building Vue.js Applications with GraphQL

By : Heitor Ramon Ribeiro
Book Image

Building Vue.js Applications with GraphQL

By: Heitor Ramon Ribeiro

Overview of this book

Since its release by Facebook in 2012, GraphQL has taken the internet by storm. Huge companies such as Airbnb and Audi have started to adopt it, while small to medium-sized companies are now recognizing the potential of this query-based API. GraphQL may seem strange at first, but as you start to read about and experience more of it, you won’t want to use REST APIs anymore. With the recipes in this book, you will learn how to build a complete real-time chat app from scratch. Starting by creating an AWS Amplify environment, you will delve into developing your first GraphQL Schema. You will then learn how to add the AppSync GraphQL client and create your first GraphQL mutation. The book also helps you to discover the simplicity and data fetching capabilities of GraphQL that make it easy for front-end developers to communicate with the server. You will later understand how to use Quasar Framework to create application components and layouts. Finally, you will find out how to create Vuex modules in your application to manage the app state, fetch data using the GraphQL client, and deploy your application to the web. By the end of this book, you’ll be well versed in proof-of-concept full-stack applications that explore the power of GraphQL with AWS Amplify, and you'll be able to use Quasar Framework to create your Vue applications.
Table of Contents (9 chapters)

Displaying cleaner data and text with custom filters

Sometimes, you may find that the user, or even you, cannot read the Unix timestamp or other DateTime formats. How can we solve this problem? When rendering the data in Vue, it's possible to use what we call filters.

Imagine a series of pipes that data flows through. Data enters each pipe in one shape and exits in another. This is what filters in Vue look like. You can place a series of filters on the same variable so that it gets formatted, reshaped, and ultimately displayed with different data while the code remains the same. The code of the initial variable is immutable in those pipes.

Getting ready

The prerequisite for this recipe is Node.js 12+.

The Node.js global objects that are required for this recipe are as follows:

  • @vue/cli
  • @vue/cli-service-global

We can continue with our to-do list project or create a new Vue project with the Vue CLI, as we learned in the Creating your first project with Vue CLI recipe.

How to do it...

Follow these steps to create your first custom Vue filter:

  1. In the App.vue file, at the <script> part, in the methods, create a formatDate function inside this property. This function will receive value as a parameter and enter the filter pipe. We can check if the value is a number because we know that our time is based on the Unix timestamp format. If it's a number, we will format based on the current browser location and return that formatted value. If the value is not a number, we just return the passed value:
<script>
import CurrentTime from './components/CurrentTime.vue';
import TaskInput from './components/TaskInput.vue';

export default {
name: 'TodoApp',
components: {
CurrentTime,
TaskInput
},
data: () => ({
taskList: []
}),
computed: {
displayList() {
return this.taskList;
}
},
methods: {
formatDate(value) {
if (!value) return '';
if (typeof value !== 'number') return value;

const browserLocale =
navigator.languages && navigator.languages.length
? navigator.languages[0]
: navigator.language;
const intlDateTime = new Intl.DateTimeFormat(
browserLocale,
{
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric'
});

return intlDateTime.format(new Date(value));
},
addNewTask(task) {
this.taskList.push({
task,
createdAt: Date.now(),
finishedAt: undefined
});
},
changeStatus(taskIndex) {
const task = this.taskList[taskIndex];
if (task.finishedAt) {
task.finishedAt = undefined;
} else {
task.finishedAt = Date.now();
}
}
}
};
</script>
  1. For the <template> part of the component, we need to pass the variable to the filter method. To do this, we need to find the taskItem.finishedAt property and make it the parameter of the formatDate method. We will add some text to denote that the task was Done at: at the beginning of the date:
<template>
<div id='app'>
<current-time class='col-4' />
<task-input class='col-6' @add-task='addNewTask' />
<div class='col-12'>
<div class='cardBox'>
<div class='container'>
<h2>My Tasks</h2>
<ul class='taskList'>
<li
v-for='(taskItem, index) in displayList'
:key='`${index}_${Math.random()}`'
>
<input type='checkbox'
:checked='!!taskItem.finishedAt'
@input='changeStatus(index)'
/>
{{ taskItem.task }}
<span v-if='taskItem.finishedAt'> |
Done at:
{{ formatDate(taskItem.finishedAt) }}
</span>
</li>
</ul>
</div>
</div>
</div>
</div>
</template>
  1. To run the server and see your component, open a Terminal (macOS or Linux) or Command Prompt/PowerShell (Windows) and execute the following command:
> npm run serve
Remember to always execute the command npm run lint --fix, to automatically fix any code lint error.

Here is the component rendered and running:

How it works...

Filters are methods that receive a value and must return a value to be displayed in the <template> section of the file, or used in a Vue property.

When we pass the value to the formatDate method, we know that it's a valid Unix timestamp, so it's possible to invoke a new Date class constructor, passing value as a parameter because the Unix timestamp is a valid date constructor.

The code behind our filter is the Intl.DateTimeFormat function, a native function that can be used to format and parse dates to declared locations. To get the local format, we can use the navigator global variable.

See also

You can find out more information about Intl.DateTimeFormat at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat.