12198


ngResourceを使い、Rails側で構築したAPIを通して新しいarticleをDBに格納した後、URLに保存された新しいarticleのidを含むeditページにリダイレクトさせたいです。

/articles/new -> articles/[newで保存されたarticleのid]/edit

以下が現在のコードです。new.html.slim(articles#new)にてarticleの新規作成を行い、DBへの格納が成功すれば、直前に格納されたidをconsole.logに出力させたいのですが、上手くいきません。いろいろ試行錯誤していますが、new_article.idがundefinedになってしまいます。。ご教授いただけますと嬉しいです。よろしくお願いいたします。

= = =

new.html.slim

[code]

    div ng-controller="ArticleController" ng-init=""
    
      form id="new_article" ng-submit="addArticle(article)"
        input type="text" ng-model="article.title"
        input type="submit" value="add"
    
[/code]

= = =

ArticleController.coffee

[code]

    angular.module('test').controller "ArticleController", ($scope, Article) ->
    
      $scope.addArticle = (article) ->
        @articleService = new Article(serverErrorHandler)
        new_article = @articleService.create(title: article.title)
        alert new_article.id
        $window.location.href = "/articles/"+new_article.id+"/edit"
        return
    
[/code]

= = =

ArticleService.coffee

[code]

    angular.module('test').factory 'Article', ($resource, $http) ->
      class Article
    
        constructor: (errorHandler) ->
          @service = $resource('/api/articles/:id',
            { id: '@id' },
            { update: { method: 'PUT' }})
          @errorHandler = errorHandler
    
        find: (id, successHandler) ->
          @service.get(id: id, ((article)->
            successHandler?(article)
            article),
            @errorHandler)
    
        create: (attrs) ->
          new @service(article: attrs).$save ((article) -> attrs.id = article.id), @errorHandler
          attrs
    
        update: (article, attrs) ->
          new @service(article: attrs).$update {id: article.id}, (-> null), @errorHandler
    
[/code]


CC BY-SA 3.0
2015-07-08T03:33:06.430
12140
2015-07-09T08:16:00.413
10441
question
javascript angularjs coffeescript
ngResourceで保存されたid値をもとにeditページにredirectさせたい


`$resource`で作成した
[Resource::$save](https://docs.angularjs.org/api/ngResource/service/$resource)
は[Promise](http://azu.github.io/promises-book/)を返します。  
[DEMO](http://jsbin.com/goforo/edit?html,js,console)  

`Article::create`の戻り値を`attrs`ではなく、`$resouce::$save()`を（つまり`Promise`）を返して下さい。  
それを、`ArticleController`で受け取ります。受け取った`Promise`は、`Promise::then`
のコールバック関数内で結果を受け取り、リダイレクトできます。修正例として

`ArticleService.coffee` の

[code]

    create: (attrs) ->
      new @service(article: attrs).$save ((article) -> attrs.id = article.id), @errorHandler
      attrs
    
[/code]

を

[code]

    create: (attrs) ->
      new @service(article: attrs).$save()
    
[/code]

に。  
  
`ArticleController.coffee`の

[code]

    $scope.addArticle = (article) ->
      @articleService = new Article(serverErrorHandler)
      new_article = @articleService.create(title: article.title)
      alert new_article.id
      $window.location.href = "/articles/"+new_article.id+"/edit"
      return
    
[/code]

を

[code]

    $scope.addArticle = (article) ->
      @articleService = new Article(serverErrorHandler)
      @articleService.create(title: article.title)
      .then (new_article)->
        console.log new_article
        $window.location.href = "/articles/"+new_article.id+"/edit"
      return
    
[/code]

にすれば、意図通りに動くのではないでしょうか。


CC BY-SA 3.0
2015-07-09T08:16:00.413
12198
2015-07-09T08:16:00.413
9834
12140
answer