質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.35%

  • JavaScript

    22087questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Node.js

    2529questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • Twitter

    842questions

    Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

  • AngularJS

    618questions

    AngularJSはオープンソースのJavaScriptフレームワークです。ブラウザ上で動作するウェブアプリケーションの開発にMVCアーキテクチャを取り入れることを目的としています。

angularjs version1.5でtwitter風アプリケーションを作る

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,401

gorimaru

score 16

前提・実現したいこと

yoemanのangular fullstack generator を使ってtwitter風のアプリケーションを作りたい。

発生している問題・エラーメッセージ

generatorで作成されたソースコードがangular1.5でよく分からない。

エラーメッセージ
ReferenceError: Auth is not defined
    at MainController.isMyStar (main.component.js:65)

ここに言語を入力

[client/app/main/main.html]

<header class="hero-unit" id="banner">
  <div class="container">
    <h1>'Allo, 'Allo!</h1>
    <p class="lead">Kick-start your next web app with Angular Fullstack</p>
    <img src="assets/images/yeoman.png" alt="I'm Yeoman">
  </div>
</header>

<div class="container">
  <br/>
  <form>
    <div class="input-group">
      <input type="text" class="form-control" placeholder="Message" ng-model="$ctrl.newThing">
      <span class="input-group-btn">
        <button type="submit" class="btn btn-primary" ng-click="$ctrl.addThing()">Add New</button>
      </span>
    </div>
  </form>

  <div ng-repeat="thing in $ctrl.awesomeThings" class="tweet">
  <div class="row">
    <h2 class="col-xs-2">
      {{thing.user.name}}
    </h2>
    <div class="arrow_box col-xs-10">
      <button ng-if="$ctrl.isMyTweet(thing)" type="button" class="close" ng-click="$ctrl.deleteThing(thing)">&times;</button>
<button ng-if="$ctrl.isMyStar(thing)" type="button" class="close" ng-click="$ctrl.unstarThing(thing)">
  <span class="glyphicon glyphicon-star" style="color: #CF7C00;" ></span>
</button>
<button ng-if="!$ctrl.isMyStar(thing)" type="button" class="close" ng-click="$ctrl.starThing(thing)"  >
  <span class="glyphicon glyphicon-star-empty"></span>
</button>

      <h2 class="message">
        {{thing.name}}
      </h2>
      <span style="float: right;">({{thing.createdAt}})</span>
    </div>
  </div>
</div>
</div>

ここに言語を入力
コード

[client/app/main/main.component.js]

import angular from 'angular';
const ngRoute = require('angular-route');
import routing from './main.routes';

export class MainController {

  /*@ngInject*/
  constructor($http, $scope, socket, Auth) {
    this.$http = $http;
    this.socket = socket;
    this.$scope = $scope;
    this.Auth = Auth;

    this.isLoggedIn = Auth.isLoggedIn;
    this.getCurrentUser = Auth.getCurrentUser;
    // this.awesomeThings = [];

    $scope.$on('$destroy', function() {
      socket.unsyncUpdates('thing');
    });
  }



  $onInit() {
    this.$http.get('/api/things')
      .then(response => {
        // this.awesomeThings = response.data;
        this.awesomeThings = response.data;
        console.log(response.data)
        this.socket.syncUpdates('thing', this.awesomeThings);
      });
  }

  isMyTweet(thing){
    Auth.isLoggedIn() && thing.user && thing.user._id===Auth.getCurrentUser()._id;
  };

  isMyStar(thing){
    Auth.isLoggedIn() && thing.stars && thing.stars.indexOf(Auth.getCurrentUser()._id)!==-1;
};


  starThing(thing) {
      this.$http.put('/api/things/' + thing._id + '/star').success(function(newThing){
          this.awesomeThing[this.awesomeThings.indexOf(thing)] = newThing;
          });
        };


  unstarThing(thing) {
    this.$http.delete('/api/things/' + thing._id + '/star').success(function(newThing){
      this.awesomeThings[this.awesomeThings.indexOf(thing)] = newThing;
    });
  };




  addThing() {
    if (this.newThing) {
      this.$http.post('/api/things', {
        name: this.newThing
      });
      this.newThing = '';
    }
  }

  deleteThing(thing) {
    this.$http.delete('/api/things/' + thing._id);
  }
}

export default angular.module('babelApp.main', [ngRoute])
  .config(routing)
  .component('main', {
    template: require('./main.html'),
    controller: MainController
  })
  .name;

ここに言語を入力
コード

[server/api/thing/thing.controller.js:]


'use strict';

import jsonpatch from 'fast-json-patch';
import Thing from './thing.model';

function respondWithResult(res, statusCode) {
  statusCode = statusCode || 200;
  return function(entity) {
    if(entity) {
      res.status(statusCode).json(entity);
    }
  };
}

function patchUpdates(patches) {
  return function(entity) {
    try {
      jsonpatch.apply(entity, patches, /*validate*/ true);
    } catch(err) {
      return Promise.reject(err);
    }

    return entity.save();
  };
}

function removeEntity(res) {
  return function(entity) {
    if(entity) {
      return entity.remove()
        .then(() => {
          res.status(204).end();
        });
    }
  };
}

function handleEntityNotFound(res) {
  return function(entity) {
    if(!entity) {
      res.status(404).end();
      return null;
    }
    return entity;
  };
}

function handleError(res, statusCode) {
  statusCode = statusCode || 500;
  return function(err) {
    res.status(statusCode).send(err);
  };
}

// // Gets a list of Things
// export function index(req, res) {
//   return Thing.find().exec()
//     .then(respondWithResult(res))
//     .catch(handleError(res));
// }
//

// Gets a list of Things
export function index(req, res) {
  return Thing.find().sort({_id:-1}).limit(20).exec()
    .then(respondWithResult(res))
    .catch(handleError(res));
}

// Gets a single Thing from the DB
export function show(req, res) {
  return Thing.findById(req.params.id).exec()
    .then(handleEntityNotFound(res))
    .then(respondWithResult(res))
    .catch(handleError(res));
}

// Creates a new Thing in the DB
export function create(req, res) {
  req.body.user = req.user;
  return Thing.create(req.body)
    .then(respondWithResult(res, 201))
    .catch(handleError(res));
}



// Upserts the given Thing in the DB at the specified ID
export function upsert(req, res) {
  if(req.body._id) {
    delete req.body._id;
  }
  return Thing.findOneAndUpdate(req.params.id, req.body, {upsert: true, setDefaultsOnInsert: true, runValidators: true}).exec()

    .then(respondWithResult(res))
    .catch(handleError(res));
}

// Updates an existing Thing in the DB
export function patch(req, res) {
  if(req.body._id) {
    delete req.body._id;
  }
  return Thing.findById(req.params.id).exec()
    .then(handleEntityNotFound(res))
    .then(patchUpdates(req.body))
    .then(respondWithResult(res))
    .catch(handleError(res));
}

// Deletes a Thing from the DB
export function destroy(req, res) {
  return Thing.findById(req.params.id).exec()
    .then(handleEntityNotFound(res))
    .then(handleUnauthorized(req, res))
    .then(removeEntity(res))
    .catch(handleError(res));
}

// exports.star = function(req, res) {
export function star(req,res) {
  Thing.update({_id: req.params.id}, {$push: {stars: req.user._id}}, function(err, num){
    if (err) { return handleError(res)(err); }
    if(num===0) { return res.send(404).end(); }
    exports.show(req, res);
  });
};

// exports.unstar = function(req, res) {
export function unstar(req,res) {
  Thing.update({_id: req.params.id}, {$pull: {stars: req.user._id}}, function(err, num){
    if (err) { return handleError(res)(err); }
    if(num === 0) { return res.send(404).end(); }
    exports.show(req, res);
  });
};

function handleUnauthorized(req, res) {
  return function(entity) {
    if (!entity) {return null;}
    if(entity.user._id.toString() !== req.user._id.toString()){
      res.send(403).end();
      return null;
    }
    return entity;
  }
}

ここに言語を入力
コード

[server/api/thing/index.js:]

'use strict';

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

var router = express.Router();

var auth = require('../../auth/auth.service');

router.get('/', controller.index);
router.get('/:id', controller.show);
router.post('/', auth.isAuthenticated(), controller.create);
router.delete('/:id', auth.isAuthenticated(), controller.destroy);

router.put('/:id/star', auth.isAuthenticated(), controller.star);
router.delete('/:id/star', auth.isAuthenticated(), controller.unstar);

module.exports = router;```  

試したこと

課題に対してアプローチしたことを記載してください twitte風のアプリケーションを作る

このサイトを参考に作りましたが、angularjsのバージョンが古い時のもので書かれています。 main.htmlで <button ng-if="$ctrl.isMyTweet(thing)" type="button" class="close" ng-click="$ctrl.deleteThing(thing)">&times;</button>

このように記述しましたが、認証されても、ボタンんが表示されない。

ng-ifを消して、とりあえずお気に入りボタンを押してみたら

starThing(thing) {  
this.$http.put('/api/things/' + thing._id + '/star').success(function(newThing){  
this.awesomeThing[this.awesomeThings.indexOf(thing)] = newThing;  
});  
};  


unstarThing(thing) {  
this.$http.delete('/api/things/' + thing._id + '/star').success(function(newThing){  
this.awesomeThings[this.awesomeThings.indexOf(thing)] = newThing;  
});  
};


この部分のawesomeThingsがundefinedというエラーがブラウザのconsoleに出てしまいます。
どなたか、どこが違うのか、
または、この参考にしたサイトのangular1.5の書き方で教えてくれないでしょうか。

バージョンは
node v6.3.1
npm v3.10.6
generator-angular-fullstack@4.0.0-rc.0 
です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2016/08/03 19:13

    コードはコードブロックで囲んでいただけませんか? ```(バッククオート3つ)で囲み、前後に改行をいれるか、コードを選択して「</>」ボタンを押すとコードブロックになります。また、URLにはリンクを張ることができます。

    キャンセル

  • gorimaru

    2016/08/03 19:18

    すみませんでした。修正してみたので、よろしければお願いします。

    キャンセル

  • flied_onion

    2016/08/04 01:06

    OS X上でいくらか試してみましたが、最初の方でコメントを追加するのすら動かなかったです。私のやり方がわるかったのでしょうが、参考までにnode, npm, generator-angular-fullstackのバージョンと、yo後に、「npm update -g generator-angular-fullstack」を実行したか否かを提示できますか?

    キャンセル

  • gorimaru

    2016/08/04 14:14

    generator-angular-fullstack@4.0.0-rc.0 を実行しました。
    文字数制限でこちらに書かせていただきました。

    キャンセル

回答 1

checkベストアンサー

0

isMyTweet, isMyStartのAuthを、this.Authにした場合どうなりますか?
addThingやdeleteThingの this.$httpが動作しているならそれで動きそうな気がします。


 追記

(8/7 18:12)

個人的に興味もあったのでやってみました。

ReferenceError: Auth is not defined

の問題は最初に書いた回答の通り、main.component.jsのisMyXX の方でAuthにthisを付けてください。
(コンストラクタは質問者さんのコードのままで)

isMyStar(thing){
      this.Auth.isLoggedIn() && thing.stars && thing.stars.indexOf(this.Auth.getCurrentUser()._id)!==-1;
  }

  isMyTweet(thing){
      this.Auth.isLoggedIn() && thing.user && thing.user._id===this.Auth.getCurrentUser()._id;
  }

ただ私の環境だと、Auth.isLoggedInとかAuth.getCurrentUserとかは、asyncの方が呼ばれてしまっていてエラーはなくなりますけど、うまくは動作してないです。
そこら辺悩んでて回答が遅れたんですが、とりあえず質問の中にあったもう一つの問題、
starThing、unstarThingでの awesomeThings が見つからない点に回答します。

awesomeThingsを参照しているところがpromiseのsuccess関数内なので、そこでのthisはコントローラではありません。
jsのクロージャ問題でのよくある解決策と同じですが、変数に代入しておきます。

starThing(thing) {
    var that = this;
    this.$http.put('/api/things/' + thing._id + '/star').success(function(newthing){
      // thatを使う。
      that.awesomeThings[that.awesomeThings.indexOf(thing)] = newthing;
    });
  }

前述の通り私の環境ではサーバー処理は呼ばれてますけど、クリックしても星の見た目は変わりません。
(既に、自分の投稿に×が見えている状態なら星の動作もうまくいくと思います。)
更新されてるかどうかは、デバッグでstarsみるとかdb見るとかすればできると思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/08/08 19:05

    丁寧な回答ありがとうございます。
    クロージャあたり、大変勉強になりました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • JavaScript

    22087questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Node.js

    2529questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • Twitter

    842questions

    Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

  • AngularJS

    618questions

    AngularJSはオープンソースのJavaScriptフレームワークです。ブラウザ上で動作するウェブアプリケーションの開発にMVCアーキテクチャを取り入れることを目的としています。