File Upload with Vue, Apollo Client and GraphQL

File Upload with Vue, Apollo Client and GraphQL

In this tutorial, I'll be showing you how to hand file uploads in GraphQL by building a fullstack app.

The tutorial will be divided into two main sections: building the GraphQL API and the frontend app. The GraphQL API will be built using Apollo Server and the frontend app will be built with Vue.js and Vue Apollo.

Table of Contents

  • Prerequisites
  • What we'll be building
  • Getting your Cloudinary keys
  • Building the GraphQL server
  • Building the frontend app
  • Fetching all photos
  • Uploading photo
  • Conclusion
Prerequisites

This tutorial assumes you conformatable with GraphQL and using it in a Vue app.

What we'll be building

For the purpose of this tutorial, we'll be building a simple photo album app, where users will be able to upload as well as view their photos. All the photos will be uploaded directly to Cloudinary. Below is a quick demo of the final app:

Getting your Cloudinary keys

Before we dive into code, let’s make sure we have our Cloudinary key in place. If you don’t already have an account with them, you can signup for free. Otherwise, login to your dashboard where you would see your account details along with your keys.

Building the GraphQL server

Now, let's start building the GraphQL server. First, let's create our project directory:

$ mkdir graphql-vue-photo-upload && cd graphql-vue-photo-upload
$ mkdir server && cd server
$ npm init -y

All the GraphQL API related code will be inside the server directory. Next, let’s install the necessary dependencies for our GraphQL server:

$ npm install graphql apollo-server cloudinary dotenv

Addition to installing Apollo Server and it dependence, we also install the Cloudinary Node.js library and a package to read environment variables.

Once that’s done installing, we can start building the GraphQL server. Create a new src directory and create a new index.js file inside it, then add the following code in it:

// server/src/index.js

const { ApolloServer } = require('apollo-server')
require('dotenv').config()
const typeDefs = require('./schema')
const resolvers = require('./resolvers')

const server = new ApolloServer({
  typeDefs,
  resolvers
})

server.listen().then(({ url }) => console.log(`Server ready at ${url}`))

Next, we need to create the schema and resolvers which our GraphQL server references. We’ll start with creating the schema. Create a schema.js inside src directory and paste the following code into it:

// server/src/schema.js

const { gql } = require('apollo-server')

const typeDefs = gql`type Photo {
    filename: String!
    path: String!
  }

  type Query {
    allPhotos: [Photo]
  }

  type Mutation {
    uploadPhoto(photo: Upload!): Photo!
  }`

module.exports = typeDefs

Here, we define a Photo type that comprises of two fields: the filename of the photo and the path to the actual photo. Then we define a single query allPhotos for fetching all uploaded photos. Lastly, we have a mutation for uploading a photo. The uploadPhoto mutation accepts a single argument, which is the photo that is to be uploaded. The argument is of the scalar type Upload, which is made available to us my Apollo Server, since it has built-in support of file upload. The mutation will return the uploaded photo.

The next, thing to do is create the resolvers. Still inside src directory, create a resolvers.js and add the code below in it:

// server/src/resolvers.js

const cloudinary = require('cloudinary').v2

cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,
  api_key: process.env.API_KEY,
  api_secret: process.env.API_SECRET
})

const photos = []

const resolvers = {
  Query: {
    allPhotos () {
      return photos
    }
  },
  Mutation: {
    async uploadPhoto (parent, { photo }) {
      const { filename, createReadStream } = await photo

      try {
        const result = await new Promise((resolve, reject) => {
          createReadStream().pipe(
            cloudinary.uploader.upload_stream((error, result) => {
              if (error) {
                reject(error)
              }

              resolve(result)
            })
          )
        })

        const newPhoto = { filename, path: result.secure_url }

        photos.push(newPhoto)

        return newPhoto
      } catch (err) {
        console.log(err)
      }
    }
  }
}

module.exports = resolvers

First, we pull in the Cloudinary library and configured it will our credentials, which are getting from the environment variables. Then we create an empty array, which will hold our photos. Next, we define the resolver for the allPhotos query, which simply returns the photos array.

For the uploadPhoto mutation, Apollo Server would return the selected file as Promise, which contains a bunch of details about the file, such as: createReadStream, filename, mimetype and encoding. In this tutorial, we’ll only be making use of the first two, so we extract them from the object. Using createReadStream, we stream the file directly to Cloudinary. Since it is an asynchronous operation we wrap it in a Promise and awaits it. If the Promise was resolved, that is, the file was uploaded successfully to Cloudinary, we create a new object containing the uploaded file name and the Cloudinary path to the file. Then we push the new object to the photos array and finally return the new object.

Lastly, if there was an error uploading the file to Cloudinary, we simply console log the erorr.

Before we wrap up the GraphQL API, let’s quickly add our environment variables. Create a .env file directly in the server directory and add the code below in it:

// server/.env

CLOUD_NAME=YOUR_CLOUD_NAME
API_KEY=YOUR_API_KEY
API_SECRET=YOUR_API_SECRET

Remember to replace the placeholders with your actual account details.

Finally, let’s start the server:

$ node src/index.js

The server should be running on [[http://localhost:4000](http://localhost:4000)](http://localhost:4000](http://localhost:4000))

Building the frontend app

As already mentioned, the frontend app will be built with Vue.js, so let’s create a new Vue.js app using the Vue CLI:

$ vue create client

When prompted, press enter to select the default preset. Start the app and leave it running while we build on it:

$ cd client
$ yarn serve

The app should be running on http://localhost:8080

Once the Vue app is created, let’s install the necessary dependencies:

$ npm install vue-apollo graphql-tag graphql apollo-cache-inmemory apollo-client apollo-upload-client

Out of these dependencies, the one that is new and that I’d like to point out is [apollo-upload-client]([https://github.com/jaydenseric/apollo-upload-client)](https://github.com/jaydenseric/apollo-upload-client)). It’s a package for Apollo Client that allows us to send GraphQL multipart requests. It will be used in place of apollo-link.

Next, let’s configure Vue Apollo and these dependencies. Update main.js as below:

// client/src/main.js

import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloClient } from 'apollo-client'
import { createUploadLink } from 'apollo-upload-client'
import Vue from 'vue'
import VueApollo from 'vue-apollo'
import App from './App.vue'

Vue.config.productionTip = false

Vue.use(VueApollo)

const apolloClient = new ApolloClient({
  link: createUploadLink({ uri: 'http://localhost:4000' }),
  cache: new InMemoryCache()
})

const apolloProvider = new VueApollo({
  defaultClient: apolloClient
})

new Vue({
  apolloProvider,
  render: h => h(App)
}).$mount('#app')

You’ll notice here we are using createUploadLink from apollo-upload-client to create the ApolloClient link, passing to it our GraphQL API endpoint.

To give our app a bit of styling, we’ll be pulling in UIKit. Add the line below to head section of index.html:





Fetching all photos

We’ll start with the GraphQL query for fetching all our photo. Create a graphql directory inside the client/src directory and with in, create a AllPhotos.js file and paste the code below into it:

// client/src/graphql/AllPhotos.js

import gql from 'graphql-tag'

export default gql`query allPhotos {
    allPhotos {
      filename
      path
    }
  }`

For the sake of simplicity, we’ll be making use of just the App.vue component. So let’s update it as below:

// client/src/App.vue


  
    
      ## Photo Album


      
        
          
            
              ![](photo.path)
            
            {{ photo.filename }}

          
        
      
    
  



Within the apollo object, we add the ALL_PHOTOS query to fetch all photos and save it in a allPhotos. Once allPhotos is populated with data from our GraphQL API, we display the photos by looping through them.

If we view our app, we should get something similar to below:

Uploading photo

Of course, we need to have uploaded some photos before we can see them. Let’s implement that now. Still inside the graphql directory, create a UploadPhoto.js and paste the code below into it:

// client/src/graphql/UploadPhoto.js

import gql from 'graphql-tag'

export default gql`mutation uploadPhoto($photo: Upload!) {
    uploadPhoto(photo: $photo) {
      filename
      path
    }
  }`

Next, add the snippet below to the template section of App.vue, just below the Photo Album heading:

// client/src/App.vue


  

Here, we have a file input field that accepts only images. On change of the input field a uploadPhoto method is triggered.

In the script section, add:

// client/src/App.vue

import UPLOAD_PHOTO from "./graphql/UploadPhoto";

methods: {
  async uploadPhoto({ target }) {
    await this.$apollo.mutate({
      mutation: UPLOAD_PHOTO,
      variables: {
        photo: target.files[0]
      },
      update: (store, { data: { uploadPhoto } }) => {
        const data = store.readQuery({ query: ALL_PHOTOS });

        data.allPhotos.push(uploadPhoto);

        store.writeQuery({ query: ALL_PHOTOS, data });
      }
    });
  }
}

We get extract the target from the input event, then call the mutate method, passing to it the UPLOAD_PHOTO mutation as well as the required argument (through the variables object). We get the selected file from the files on the target object. Once the mutation is executed, we update the cache by adding the newly uploaded photo to the allPhotos array.

Conclusion

So in this tutorial, we have seen how to handle file uploads in GraphQL using Apollo Server on the server side and Vue and Vue Apollo on the client side. Though we used Cloudinary to store our photos, you can easily wrap it for any other cloud storage service or you can even save directly to your own local filesystem.

10 Best Vue Icon Component For Your Vue.js App

10 Best Vue Icon Component For Your Vue.js App

In this article, I will collect 10 Vue icon component to bring more interactivity, better UI design to your Vue application.

Icons are the vital element of the user interface of the product enabling successful and effective interaction with it. In this article, I will collect 10 Vue icon component to bring more interactivity, better UI design to your Vue application.

1. Animated SweetAlert Icons for Vue

A clean and simple Vue wrapper for SweetAlert's fantastic status icons. This wrapper is intended for users who are interested in just the icons. For the standard SweetAlert modal with all of its bells and whistles, you should probably use Vue-SweetAlert 2

Demo: https://vue-sweetalert-icons.netlify.com/

Download: https://github.com/JorgenVatle/vue-sweetalert-icons/archive/master.zip

2. vue-svg-transition

Create 2-state, SVG-powered animated icons.

Demo: https://codesandbox.io/s/6v20q76xwr

Download: https://github.com/kai-oswald/vue-svg-transition/archive/master.zip

3. Vue-Awesome

Awesome SVG icon component for Vue.js, with built-in Font Awesome icons.

Demo: https://justineo.github.io/vue-awesome/demo/

Download: https://github.com/Justineo/vue-awesome/archive/master.zip

4. vue-transitioning-result-icon

Transitioning Result Icon for Vue.js

A scalable result icon (SVG) that transitions the state change, that is the SVG shape change is transitioned as well as the color. Demonstration can be found here.

A transitioning (color and SVG) result icon (error or success) for Vue.

Demo: https://transitioning-result-icon.dexmo-hq.com/

Download: https://github.com/dexmo007/vue-transitioning-result-icon/archive/master.zip

5. vue-zondicons

Easily add Zondicon icons to your vue web project.

Demo: http://www.zondicons.com/icons.html

Download: https://github.com/TerryMooreII/vue-zondicons/archive/master.zip

6. vicon

Vicon is an simple iconfont componenet for vue.

iconfont
iconfont is a Vector Icon Management & Communication Platform made by Alimama MUX.

Download: https://github.com/Lt0/vicon/archive/master.zip

7. vue-svgicon

A tool to create svg icon components. (vue 2.x)

Demo: https://mmf-fe.github.io/vue-svgicon/v3/

Download: https://github.com/MMF-FE/vue-svgicon/archive/master.zip

8. vue-material-design-icons

This library is a collection of Vue single-file components to render Material Design Icons, sourced from the MaterialDesign project. It also includes some CSS that helps make the scaling of the icons a little easier.

Demo: https://gitlab.com/robcresswell/vue-material-design-icons

Download: https://gitlab.com/robcresswell/vue-material-design-icons/tree/master

9. vue-ionicons

Vue Icon Set Components from Ionic Team

Design Icons, sourced from the Ionicons project.

Demo: https://mazipan.github.io/vue-ionicons/

Download: https://github.com/mazipan/vue-ionicons/archive/master.zip

10. vue-ico

Dead easy, Google Material Icons for Vue.

This package's aim is to get icons into your Vue.js project as quick as possible, at the cost of all the bells and whistles.

Demo: https://material.io/resources/icons/?style=baseline

Download: https://github.com/paulcollett/vue-ico/archive/master.zip

I hope you like them!

Collection of 10 Vue Markdown Component for Vue.js App in 2020

Collection of 10 Vue Markdown Component for Vue.js App in 2020

Markdown is a way to style text on the web. The 10 Vue markdown components below will give you a clear view.

Markdown is a way to style text on the web. You control the display of the document; formatting words as bold or italic, adding images, and creating lists are just a few of the things we can do with Markdown.

The 10 Vue markdown components below will give you a clear view.

1. Vue Showdown

Use showdown as a Vue component.

View Demo

Download Source

2. showdown-markdown-editor

A markdown editor using codemirror and previewer using showdown for Vue.js.

View Demo

Download Source

3. markdown-it-vue

The vue lib for markdown-it.

View Demo

Download Source

4. perfect-markdown

perfect-markdown is a markdown editor based on Vue & markdown-it. The core is inspired by the implementation of mavonEditor, so perfect-markdown has almost all of the functions of mavonEditor. What's more, perfect-markdown also extends some features based on mavonEditor.

View Demo

Download Source

5. v-markdown-editor

Vue.js Markdown Editor component.

View Demo

Download Source

6. markdown-to-vue-loader

Markdown to Vue component loader for Webpack.

View Demo

Download Source

7. fo-markdown-note Component for Vue.js

fo-markdown-note is a Vue.js component that provides a simple Markdown editor that can be included in your Vue.js project.

fo-markdown-note is a thin Vue.js wrapper around the SimpleMDE Markdown editor JavaScript control.

View Demo

Download Source

8. Vue-SimpleMDE

Markdown Editor component for Vue.js. Support both vue1.0 & vue2.0

View Demo

Download Source

9. mavonEditor

A nice vue.js markdown editor. Support WYSIWYG editing mode, reading mode and so on.

View Demo

Download Source

10. vue-markdown

A Powerful and Highspeed Markdown Parser for Vue.

View Demo

Download Source

Thank for read!

10+ Must-Have Tools & Libraries for Vue.js Development

10+ Must-Have Tools & Libraries for Vue.js Development

If you are serious about Vue development, sooner or later you’ll meet some fundamental tools and libraries which stand out from the crowd. Using them will level up your career as a Vue developer, and make you feel like a professional.

If you are serious about Vue development, sooner or later you’ll meet some fundamental tools and libraries which stand out from the crowd. Using them will level up your career as a Vue developer, and make you feel like a professional.

Vue continues to grow in popularity and is rapidly being adopted by many developers, and Vue.js tools are popping up everywhere. This is not without reason: Vue’s shallow learning curve, clear functionality-driven structure, and excellent documentation make it easy for novices to pick it up, and for more experienced developers to make a switch from other frameworks like React or Angular.

I’ve compiled a list of the most notable tools and libraries you should know and eventually use in your Vue.js projects. Unlike many other articles out there, which list only UI component libraries, this compilation explores a much broader mixture of tools, libraries, and plugins in the Vue ecosystem.

I’ve selected these based on their usefulness, effectiveness, and uniqueness — not their GitHub popularity or star ratings.

Enough talk: here they are, the top ten.

Vue CLI

It seems that having some kind of CLI tool is a must for every JavaScript application framework these days. Vue is no exception. Vue CLI is a fully-featured set of tools for rapid Vue development. Besides the usual project scaffolding, it allows you to experiment with new ideas even without creating a full project, by using its instant prototyping feature.

By default, Vue CLI offers support for the major web development tools and technologies, such as Babel, TypeScript, ESLint, PostCSS, PWA, Jest, Mocha, Cypress, and Nightwatch. This is possible thanks to its extensible plugin system. This means the community can build and share reusable plugins for common needs.

But the icing on the cake is the powerful GUI (Vue UI, which comes with the CLI) which allows you to create your project easily, and then configure and manage it along the way without the need for ejection.

Vue CLI

VuePress

The next big player in Vue’s ecosystem is VuePress, a Vue-powered static site generator. Initially created as a tool for writing technical documentation, now it’s a small, compact, and powerful headless CMS. Since version 1.x, it has offered great blogging features and a powerful plugin system. It comes with a default theme (tailored to technical documentation), but you can also build custom themes or use a pre-made option from the community.

In VuePress, you write the content in Markdown, which is then transformed to pre-rendered static HTML files. Once those files are loaded, your site runs as a single-page application powered by Vue, Vue Router and Webpack.

One of the main benefits of VuePress is that you can include Vue code or components within your Markdown files. This gives you great power and flexibility because you can develop your site almost like a regular Vue app, with all benefits that come from that.

VuePress

Gridsome

Gridsome has many similarities with VuePress but it takes a different and very powerful approach when dealing with data sources. It allows you to connect and use many different kinds of data in your app, which are then unified in one GraphQL layer. Basically, Gridsome uses Vue for front-end functionality and GraphQL for data management. The way this works can be summarized in the following three steps:

  1. You provide content in the Markdown, JSON, YAML, or CVS data formats, or import it from a CMS like WordPress or Drupal.
  2. The content is turned into the GraphQL layer, which provides centralized data management. Then you use that data to build your app with Vue.
  3. You deploy pre-rendered HTML files to static web hosts or CDNs such as Netlify, Amazon S3, Now.sh, Surge.sh, etc.

There are some great best practices that Gridsome provides out of the box, such as code splitting, asset optimization, progressive images, and link prefetching. So, Gridsome is fast, and also PWA-ready and SEO-friendly.

Gridsome

Vuex

State management is one of the main problems developers meet in web app building. To solve this, Vue offers a state management system — Vuex. It serves as a centralized store for all the components in an application, where the state can only be mutated predictably. A store is a special object which is divided into four parts:

  • state – an object which stores the app’s data
  • getters – an object containing methods used to abstract the access to the state
  • mutations – an object containing methods that directly affect the state
  • actions – an object containing methods used to trigger mutations and execute asynchronous code

The store can be also divided into modules for better maintainability.

Vuex

Nuxt

When it comes to using server-side rendering (SSR), Nuxt is the usual way to go. It’s a simple and straightforward framework for building universal applications. It’s also modular, so you can use only those modules that you need for your app.

With Nuxt, you can create server-rendered apps (SSR), single-page applications (SPA), progressive web applications (PWA), or just use it as a static site generator.

In brief, Nuxt saves you from the tedious job of structuring and optimizing your app, giving you a streamlined and more enjoyable development experience.

Nuxt

Vuetify

Vuetify is one of the greatest UI component libraries out there. It offers a large set of crafted components (80+) based on the Material Design spec, which is enough for almost any app’s needs.

You can use it to build SSR apps, SPAs, PWAs, and mobile apps. You can start new apps or add them to existing applications. It offers free and premium themes, but you can build your own as well. It also provides a system to pick and choose only the components in use, thus reducing the final size of your app dramatically.

All Vuetify components are very well documented and clear examples are provided.

Vuetify

Quasar

Quasar is the JavaScript version of the “write once, run everywhere” Java philosophy. It’s a universal, Vue-powered framework that allows you to write apps for different platforms with the same code base. SPAs, PWAs, SSR apps, Hybrid Mobile Apps or Multi-platform Desktop Apps, you name it!

It has great documentation and a massive set of components designed with performance and responsiveness in mind. Quasar integrates best practices (HTML/CSS/JS minification, cache busting, tree shaking, source mapping, code-splitting with lazy loading, ES6 transpiling, code linting, accessibility) by default so you can focus primarily on your app’s features. It also provides a CLI tool for effortless scaffolding of new projects.

Quasar

Storybook

Vue is a primarily component-based framework, so writing good, efficient components is crucial for every app developer. In this undertaking Storybook might come in very handy. It allows you to develop, manage, and test UI components in an easy-to-use and isolated environment. The tool enables developers to create components independently from the main app and showcase them interactively in an isolated development environment without worrying about app-specific dependencies and requirements.

Storybook provides plenty of add-ons, plus a flexible API to customize your storybook as you need. You can also export as a static web app and deploy your project to any HTTP server.

Storybook

Vue Apollo

There is a lot of buzz around GraphQL lately. So if you are already familiar with it and want to integrate it with Vue, you should try Vue Apollo. This library makes the use of Vue and GraphQL/Apollo together smooth and pleasant.

Vue Apollo

Eagle.js

Eagle.js is a powerful, flexible and unique slideshow system built with Vue. It allows you to create easy-to-reuse components, slides, and styles across your presentations. It also supports animations, themes, and interactive widgets which are great for making web demos. Eagle.js has a simple and hackable API, so you have the real freedom to craft the slideshows you want.

One of the greatest things you can do with this library is to place a slide in a separate file and then reuse it in other slideshows. You can also import the slides of a particular slideshow inside another one. With such a powerful tool, you can make complex, interactive, and entertaining presentations.

Eagle.js

Bonus: 5 More Notable Vue Tools and Libraries

Here is a little bonus for you: another five tools and libraries which deserve your attention.

  • Vue DevTools is a great browser extension for debugging Vue and Vuex applications.
  • Vue Test Utils is a collection of useful utilities for testing Vue components.
  • Vue Router is the official router for Vue.
  • Vue Native is a JavaScript framework for mobile apps, similar to React Native.
  • Weex is a framework for building mobile apps with modern web technologies, including Vue.
Conclusion

Now you have the tools you need to build awesome projects, no matter what they are: websites, apps, libraries, plugins, the list goes on. Go build something great!