Monthly archives "10月 2014"

herokuのMEANからCloudinaryに画像をアップロードしよう

前提は下記の通り。
1.yeoman angular-fullstakでMEAN(MongoDB+Express+AngularJS+Node.js)アプリを作成済み
 この方法はYEOMANを使ってMEAN(MongoDB+Express+AngularJS+Node.js)を作成しようを参照すること
2.アプリをherokuにデプロイ済み
 この方法はangular-fullstackをherokuにデプロイする方法を参照すること
 
手順は下記の通り。
 

1.herokuにCloudinaryアドオンを追加

heroku toolbeltから下記コマンドを実行

heroku addons:add cloudinary --app foo

※fooはherokuのアプリ名
 

2.Gruntfile.jsに環境変数CLOUDINARY_URLを設定

herokuのConfig variablesを参照して環境変数CLOUDINARY_URLをGruntfile.jsに設定する。
下記はGruntfile.jsの例。

module.exports = function (grunt) {
  var localConfig;
  try {
    localConfig = //require('./server/config/local.env');
      {
        DOMAIN: 'http://localhost:9000',
        SESSION_SECRET: "foo-secret",

        FACEBOOK_ID: 'app-id',
        FACEBOOK_SECRET: 'secret',

        TWITTER_ID: 'app-id',
        TWITTER_SECRET: 'secret',

        GOOGLE_ID: 'app-id',
        GOOGLE_SECRET: 'secret',

        CLOUDINARY_URL: 'cloudinary://999999999999999:XXXXXXXXXXXXXXXXXXXXXXXXXXXX@xxxxxxxxx',

        // Control debug level for modules using visionmedia/debug
        DEBUG: ''
      };
  } catch(e) {
    localConfig = {};
  }

※本来環境変数は./server/config/local.env.jsに設定すれば良いはずだが、なぜかgruntが読み込んでくれないのでGruntfile.jsに直接記入している。
 

3.npmでcloudinaryをインストール

端末から下記コマンドを実行

npm install cloudinary --save

 

4.bowerでangular-file-uploadをインストール

参考文献:angular-file-upload#Yeoman with bower automatic include
端末から下記コマンドを実行

bower install ng-file-upload --save
bower install ng-file-upload-shim --save

 

5.npmでconnect-multipartyをインストール

参考文献:How to get uploaded file in Node.js Express app using angular-file-upload
connect-multipartyをインストールする。
端末から下記コマンドを実行

npm install connect-multiparty --save

 

6.bower.jsonのangular-file-uploadの読み込み順序を変更

参考文献:angular-file-upload#install
bower.jsonの依存順序を下記通りにする。
bower.jsonの依存順序を変更することでgrunt serve時にclient/index.htmlのbower管理のjavascript読み込み順序も変更される。

{
  "dependencies": {
    "ng-file-upload-shim": "~1.6.12",
    "angular": ">=1.2.*",
    "ng-file-upload": "~1.6.12"
  }
}

 

7.client側ソースコード追加

参考文献:angular-file-upload#usage
client側ソースコードを追加する。
サンプルとほぼ同じだがソースコード例を示す。
HTML例

<div ng-controller="MyCtrl">
  <input type="file" ng-file-select="onFileSelect($files)">
</div>

※scriptの読み込みはclient/index.htmlで行われる。
 
app.js

angular.module('myApp', [
  'ngCookies',
  'ngResource',
  'ngSanitize',
  'btford.socket-io',
  'ui.router',
  'ui.bootstrap',
  'pascalprecht.translate',
  'angularFileUpload'  //追加
])

 
javascript例

angular.module('myApp')
  .controller('MyCtrl', function($scope, $upload) {
    $scope.onFileSelect = function($files) {
      for (var i = 0; i < $files.length; i++) {
        var file = $files[i];
        $scope.upload = $upload.upload({
          url: 'api/myapi', // server側API例
          file: file
        }).progress(function(evt) {
          console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
        }).success(function(data, status, headers, config) {
          console.log(data);
        });
      }
    };
  });

 

8.server側ソースコード追加

参考文献:
angular-file-upload node.js example
How to get uploaded file in Node.js Express app using angular-file-upload
Cloudinary using with node.js
server側ソースコードを追加する。
yo angular-fullstack:endpointでserverにmyapiという名前のAPIを追加した場合の例を示す。
ファイル:server/api/myapi/index.js

'use strict';

var express = require('express');
var controller = require('./myapi.controller');

var router = express.Router();

var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();

router.post('/', multipartMiddleware, controller.create);

module.exports = router;

 
ファイル:server/api/myapi/myapi.controller.js

'use strict';

var fs = require('fs');
var cloudinary = require('cloudinary');

exports.create = function(req, res) {
  if(req.files.file) {
    var stream = cloudinary.uploader.upload_stream(function(result) {
      return res.send(200);
    });
    fs.createReadStream(req.files.file.path).pipe(stream);
  } else {
    return res.send(400);
  }
};

 
以上で完成。
clientで画像が選択されるたびにserver経由でcloudinaryに画像ファイルがアップロードされる。
 


3

BootstrapのサンプルNestingのドロップダウンが開かない

BootstrapのサンプルNestingのドロップダウンが開かないので、その修正箇所を説明する。
 
【修正前】
http://getbootstrap.com/components/#btn-groups-nested

<div class="btn-group">
  <button type="button" class="btn btn-default">1</button>
  <button type="button" class="btn btn-default">2</button>

  <div class="btn-group">
    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
      Dropdown
      <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" role="menu">
      <li><a href="#">Dropdown link</a></li>
      <li><a href="#">Dropdown link</a></li>
    </ul>
  </div>
</div>

 
【修正後】

<div class="btn-group">
  <button type="button" class="btn btn-default">1</button>
  <button type="button" class="btn btn-default">2</button>

  <div class="btn-group">
    <div class="dropdown">
      <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
        Dropdown
        <span class="caret"></span>
      </button>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Dropdown link</a></li>
        <li><a href="#">Dropdown link</a></li>
      </ul>
    </div>
  </div>
</div>

 
要は

<div class="btn-group">

の直下に

<div class="dropdown">

が必要。
 


0