Build A Photo Gallery app with Ionic2, Cloudinary, NodeJs And MongoDB part 1

nionic 2 photo upload with nodejs

n

n

n

n

n

nOverview

nUploading files and images in ionic app to some remote server is without doubt one of the most required functions.
n

n

n

nThis two parts article will show you how images can be upload to Cloudinary server via NodeJS API from ionic2 app.

n

n

n

nCloudinary is a cloud-based service that provides an end-to-end image management solution including uploads, storage, administration, image manipulation, and delivery.

n

n
nYou can easily upload images to the cloud, automatically perform smart image manipulations without installing any complex software. All your images are then seamlessly delivered through a fast CDN, optimized and using industry best practices.
n
nnnn
n
nCloudinary offers comprehensive APIs and administration capabilities and is easy to integrate with new and existing web and mobile applications.n

n

n

n

n

n

nIn this first part, am going to create the client part of our application which the Ionic2 app, take photo with camera, or choose existing photo from gallery and send it to a remote server.

n

n

n

nIn the second part I will create the NodeJS API will be done.

n
n

nSetting up the Ionic Project

nLets start by creating a blank Ionic2 project.
n

ionic start ionic-cloudinary blank --v2nionic platform add androidn

nNow that the project has been created and android platform has been added, lets install all the native plugins the app required:n
n

    n

  1. cordova-plugin-file
  2. n

  3. cordova-plugin-file-transfer
  4. n

  5. cordova-plugin-camera
  6. n

n

ionic plugin add cordova-plugin-filenionic plugin add cordova-plugin-file-transfernionic plugin add cordova-plugin-camerann

nNow that we have installed all the plugins needed for this project, lets create the upload picture page by running the following command in our command prompt:nn
n

ionic generate page newpostnn

n

nProject Structure 

nThe application structure should look like the one bellow:
n
n

n

n
n
nWe will start modifying the home page to display the list of images fetched from the server using angularjs http service.
nThe final home page markup should look like so:
n

n  n    n      Galleryn    n    n      n    n  nnn  n    n    n      n        {{item.title}}n      n      {{item.description}}n    n  n  nn

n
n
nAs you can see, there nothing complex here, we just used ngRepeat to loop through the array of photos and render them withing ion-card component.
nnnnnThe next step is to wire up the code that will be responsible for fetching of the images in home.ts file like so:
n
n
n

import { Component } from '@angular/core';nimport { NavController, LoadingController } from 'ionic-angular';nimport { Newpost } from '../../pages/newpost/newpost';nimport { PostService } from '../../providers/post-service';nn@Component({n  selector: 'page-home',n  templateUrl: 'home.html'n})nexport class HomePage {n  posts: any;n  constructor(public navCtrl: NavController,n    private postService: PostService, private loadingCtrl: LoadingControllern  ) {nnn  }nn  ionViewDidLoad() {n    this.getPosts();n  }nn  getPosts() {n    let loader = this.loadingCtrl.create({n      content: "Loading Photos..."n    });n    loader.present();n    this.postService.getPosts().subscribe((val) => {n      this.posts = val.posts;n      loader.dismiss();n    });n  }nnnnn  addNewPhoto() {n    this.navCtrl.push(Newpost);n  }nn}nnnn

nIn the home.ts file has two imports statement to NewPost page and PostService which have not created. Now let add the PostService by typing this ionic cli command:
n
n

ionic generate provider PostServicenn

nModify the post-service.ts file like so:nnn
n
n

import { Injectable } from '@angular/core';nimport { Http } from '@angular/http';nimport 'rxjs/add/operator/map';nn@Injectable()nexport class PostService {n  posts: any;n  n  constructor(public http: Http) {nn  }nn  getPosts() {n    return this.http.get('https://photocloudapp.herokuapp.com/api/v1/posts')n      .map(res => res.json());n  }nn n}nn

nAs you can see the only method we have here is getPosts. This method just return angular’s http get response from our API endpoint (We are going to create the API in the second part of this article)n
n
nLet’s modify the newpost html page to look like so:
n
n
n

n  n    
nn
n
nn
n
nn n nn n Post Titlen n nn n Descriptionn n nn n n nnn nn
nnn

nThere is nothing complex about this view. As you can see we are also going to save the picture title and description.
n
nWe are going to do a bit of work in the newpost.ts file.
nnnn
nThe first task is to import the required modules on this file. As you know we are going to be using some native plugins, so let’s import those plugins:
n
n

import { File, Camera, Transfer } from 'ionic-native';

n


n
nWe also need to import LoadingController and ActionSheetController like so:n
n
n

import { NavController, LoadingController, ActionSheetController } from 'ionic-angular';

n
nThe final code in the newpost.ts look like this:
n
n
n nn
n

import { Component } from '@angular/core';nimport { NavController, LoadingController, ActionSheetController } from 'ionic-angular';nimport { File, Camera, Transfer } from 'ionic-native';nimport { HomePage } from '../home/home';nndeclare var cordova: any;nn@Component({n  selector: 'page-newpost',n  templateUrl: 'newpost.html'n})nexport class Newpost {n  postTitle: any;n  desc: any;n  imageChosen: any = 0;n  imagePath: any;n  imageNewPath: any;nn  constructor(public navCtrl: NavController,n    public actionSheet: ActionSheetController,n    private loadingCtrl: LoadingController) {nn  }nn  ionViewDidLoad() {nn  }nnn  uploadPhoto() {n    let loader = this.loadingCtrl.create({n      content: "Please wait..."n    });n    loader.present();nn    let filename = this.imagePath.split('/').pop();n    let options = {n      fileKey: "file",n      fileName: filename,n      chunkedMode: false,n      mimeType: "image/jpg",n      params: { 'title': this.postTitle, 'description': this.desc }n    };nnn    const fileTransfer = new Transfer();nn    fileTransfer.upload(this.imageNewPath, 'https://photocloudapp.herokuapp.com/api/v1/post/upload',n      options).then((entry) => {n        this.imagePath = '';n        this.imageChosen = 0;n        loader.dismiss();n        this.navCtrl.setRoot(HomePage);n      }, (err) => {n        alert(JSON.stringify(err));n      });n  }nn  chooseImage() {nn    let actionSheet = this.actionSheet.create({n      title: 'Choose Picture Source',n      buttons: [n        {n          text: 'Gallery',n          icon: 'albums',n          handler: () => {n            this.actionHandler(1);n          }n        },n        {n          text: 'Camera',n          icon: 'camera',n          handler: () => {n            this.actionHandler(2);n          }n        },n        {n          text: 'Cancel',n          role: 'cancel',n          handler: () => {n            console.log('Cancel clicked');n          }n        }n      ]n    });nn    actionSheet.present();n  }nnn  //}nn  actionHandler(selection: any) {n    var options: any;nn    if (selection == 1) {n      options = {n        quality: 75,n        destinationType: Camera.DestinationType.FILE_URI,n        sourceType: Camera.PictureSourceType.PHOTOLIBRARY,n        allowEdit: true,n        encodingType: Camera.EncodingType.JPEG,n        targetWidth: 500,n        targetHeight: 500,n        saveToPhotoAlbum: falsen      };n    } else {n      options = {n        quality: 75,n        destinationType: Camera.DestinationType.FILE_URI,n        sourceType: Camera.PictureSourceType.CAMERA,n        allowEdit: true,n        encodingType: Camera.EncodingType.JPEG,n        targetWidth: 500,n        targetHeight: 500,n        saveToPhotoAlbum: falsen      };n    }nn    Camera.getPicture(options).then((imgUrl) => {nn      var sourceDirectory = imgUrl.substring(0, imgUrl.lastIndexOf('/') + 1);n      var sourceFileName = imgUrl.substring(imgUrl.lastIndexOf('/') + 1, imgUrl.length);n      sourceFileName = sourceFileName.split('?').shift();n      File.copyFile(sourceDirectory, sourceFileName, cordova.file.externalApplicationStorageDirectory, sourceFileName).then((result: any) => {n        this.imagePath = imgUrl;n        this.imageChosen = 1;n        this.imageNewPath = result.nativeURL;nn      }, (err) => {n        alert(JSON.stringify(err));n      })nn    }, (err) => {n      alert(JSON.stringify(err))n    });nn  }n  n}nnn

nAnd the last thing here is the sass file for the two pages:nnnHome.scss filenn
n

page-home {n  ion-card {n    margin: 0;n    width: 100%;n    border-radius: 0;n    ion-card-content {n      padding: 3px 5px 10px 3px !important;n    }n  }n}nn

nNewPost.scss filenn
n

page-newpost {nion-card{n    margin: 3px !important;n    width: calc(100% - 6px) !important;n    .uploadWrap{n        ion-icon{n            color:#777;n            font-size: 150px;n            text-align: center !important;n            display: block;n        }n    }n    button{n        height: 40px !important;n    }n}n}nn

n
nYou can find the entire source code of this article here.
n
nIn the next post we are going to sign up for free cloudinary account, create our Nodejs API and deploy to Heroku.
n
nI hope this helps.nnHappy coding.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top