Adonis js is a great Node js framework. It comes with a powerful CLI that automates the work. The long list of features makes it much popular in a short time span. On the other side Vue js is the love of JavaScript developers. It’s faster, easier and its component-based architecture makes it convenient for any development environment. So in this tutorial, we will explain Adonis js Vue image upload.

A dynamic image upload can genuinely improve your website UX. However, if you are a PHP developer and looking for the same tutorial. Then you can read Codeigniter vue image upload tutorial.

We have chosen Vue for this tutorial because of Vue js advantages. If you are not satisfied with our opinion then you may like to check out Vue vs React.

Adonis js Vue image upload

First of all, you will need the following things to be installed.

* npm, Node Js, Adonis CLI

So make sure you have installed them all. Now once the Adonis CLI has been installed create a new project with the following command.

adonis new image-upload

Here image-upload is the project name. After the above command executed successfully. It will create a folder named as the project name within the directory where its executed.

Now open the project directory within your favorite text editor and follow the sections below.

Creating the view

First of all, go inside the resources/views directory and create a new file called upload.edge. Now we are using bootstrap to make things beautiful. However, you can use a framework of your choice.

We are just creating a bootstrap card and adding the form to it.

<div class="container pt-5" id="app">
	<div class="row justify-content-center">
		<div class="col-md-8">
			<div class="card">
				<div class="card-body">
					<!-- form will be added here -->
				</div>
			</div>
		</div>
	</div>
</div>

In the above code, we have created a card at the center of the screen. Now let’s add code to create the form as follows.

<form method="POST" action="upload" enctype="multipart/form-data" @submit.prevent="upload">
	{{ csrfField() }}
	<div class="form-group">
  		<input type="file" name="profile_pic" class="form-control" id="image" />
  	</div>
  	<button type="submit" class="btn btn-primary">Submit</button>
</form>

Look at the above form. As we are uploading files so enctype is the required attribute. After that, we have added the submit event of Vue js to the form. In addition, to submit, we have also added prevent. So whenever we hit the submit button the form will not submit rather it will execute the upload method.

After the form, we have used the csrfField method. This method creates a hidden csrf field that helps in preventing XSS attacks. Now the file field has been added along with the submit button.

Creating the script

This one is the most interesting section of our Adonis js vue image upload tutorial.

We need 3 particular scripts for this tutorial. jQuery(optional), Axios and Vue js. We are using them locally but you can use the CDN available on the internet.

Once you have added those three scripts in your view the fourth script will contain our custom code. So let’s check out how it will look like.

var app = new Vue({
  	el: '#app',
  	data: {
  		file_data: '',
  		form_data: {},
  	},
  	methods: {
  		upload() {	
	    
	    }
	}
});

The above code will create a new vue instance and bind it to the element with the id app. After that, we have created two data variables called file_data and form_data. Finally, we have added the upload method.

Now we need to write code for our upload method.

this.file_data = $('#image').prop('files')[0];
this.form_data = new FormData();
this.form_data.append('profile_pic', this.file_data);
this.form_data.append('csrf-token', "{{ csrfToken }}");

First of all, we have stored the file name into the file_data variable. After that, we have used the FormData class to initialize an empty form_data. Later that we have added two fields the file and the csrf-field to the form. The csrfToken actually returns the value of csrf field.

let url = "upload";
var self = this
axios
	 .post(url, this.form_data).then((res) => {
	    if(res.data.message) {
	        $('#message').html('<p class="text-danger">' + res.data.message + '</p>');
	   	} else {
	       	$('#message').html('<p class="text-success">Image has been uploaded successfully<p>');
	    }
});

In the above code, we have stored the upload URL in a variable called url. Next, we have used Axios and used a post request. The post request returns a promise.

Generally for ajax requests if the file is not valid Adonis automatically returns a JSON response. Which contains a message within the data object.

On the other side if it’s valid then it just returns data as a string that contains the word success.

So if the message has existed in the promise response then we will display the errors on a card with id message. Else we will display a custom success message.

Finally, our view portion is done. Now let’s move to the start/routes.js and define our back-end logic.

Writing the backend logic

It’s the last section of our Adonis js vue image upload tutorial.

We will display our upload view on the root URL. So at first change the line as follows.

Route.on('/').render('upload')

Now as we will upload photos so we will need the file helper of Adonis js. You can import it as follows.

const Helpers = use('Helpers')

Now we are ready to define our upload URL logic. First, let’s create it and add the validation rules.

Route.post('upload', async ({ request }) => {
  	const profilePic = request.file('profile_pic', {
    	types: ['image'],
    	size: '2mb'
  	})
})

The request object within the curly braces contains all the submitted data. The constant profilePic contains the validation rules in it. We haven’t dived much deeper so we just added two simple validation rules.

The file must be an image of maximum 2mb.

Now we need to move the uploaded file to a folder. For this purpose create a folder called uploads within the public directory. Now you can add the code as follows to move the uploaded file.

var name = profilePic.clientName
var ext = name.split('.')[1]
var ts = new Date().valueOf()
var fileName = ts + '.' + ext

await profilePic.move(Helpers.publicPath('uploads'), {
    name: fileName
})

In the first 4 lines, we have extracted the image extension from the uploaded image. Then we have used the current timestamp as the file name. In this way, each image will contain a unique name.

We haven’t done yet. What if the file is not valid or it’s not moved. Let’s fix this one now.

if (!profilePic.moved()) {
    return profilePic.error()
}

So if the file is not moved we will return the error object. If there’s no error then Adonis will send an auto-generated success response.

So finally we have reached the end of our Adonis js vue image upload tutorial. Hope you’ve liked this one. However, if you think we have missed something let us know by commenting below.