使用$ resource返回未定义的GET请求

时间:2014-08-09 23:05:15

标签: javascript angularjs

$scope.newPost.content = "Part 2 of phrase"
$scope.newPost.content = Phrase.get({id: $scope.newPost.phrase_id}).$promise.then(
  (result) ->
    return result.content + " " + $scope.newPost.content 
)

console.log($scope.newPost.content)

这应该输出我的连接字符串。相反,$ scope.newPost.content返回:

Object {then: function, catch: function, finally: function}
POST http://localhost:3000/api/v1/posts.json 422 (Unprocessable Entity) //content cant be blank

我做错了什么。

3 个答案:

答案 0 :(得分:0)

这是一个非常常见的错误,承诺在开始时有点难以掌握。

我会尝试逐行解释,下面的顺序与运行代码的顺序相同。

1)$ scope.newPost.content ="短语"

的第2部分

有了这个,你已经为你的newPost.content变量分配了一个字符串,到目前为止,这么好

2)$ scope.newPost.content = Phrase.get({bla bla bla ...});

现在这是用promise对象替换前一个字符串,它不再是一个字符串。 这样的事情是可能的,因为javascript疯狂灵活的非强类型方式,大声笑。这不会等到服务器上的内容完成,而且那些与您混淆的是,下一行将在此之后立即运行,并且将具有错误的值。

3)console.log($ scope.newPost.content)

这就是事情变得混乱的地方,现在,你的newPost.content不是一个字符串,它是来自2的承诺,并且控制台上的输出证明了这一点。 (该输出是一个promise对象)。

你的newPost.content只有在2的promise解析时才会有你的串联字符串,这可能需要很长或很短的时间才能完成,重要的是要注意它并没有阻塞其余的代码,所以3将在2 ...之后立即执行 把诺言想象成在另一个线程中运行的东西。

所以,我的原始答案仍然是,你的变量只有在promise解析后才会有所需的值,所以你必须在那之后采取行动,通常在then函数内部,我做了一些修改来说明并避免无用的分配:

var part2 = "Part 2 of phrase"
Phrase.get({id: $scope.newPost.phrase_id}).$promise.then(
  function(result){
      $scope.newPost.content = result.content + ' ' + part2;
      console.log($scope.newPost.content);
  }
);

希望有所帮助。

答案 1 :(得分:0)

console.log行在异步调用之外,这意味着它将在检索资源之前运行。

  • 代码中的事件顺序为:
    1. 将字符串分配给scope.newPost.content
    2. 开始检索资源。
    3. 将一个新值分配给scope.newPost.content并立即返回get,它看起来像一个promise对象。
    4. 将此promise对象写入控制台日志。
    5. 接收资源获取电话的结果。
    6. 将此调用的结果分配给scope.newPost.content

正如您应该看到的项目4 - 6不符合您的希望。

如果要编写异步调用的结果,则需要在解析promise之后进行。最简单的地方是then回调函数。

答案 2 :(得分:0)

我的问题在于误解了承诺的运作方式 它是通过在promise之外定义或实例化变量来解决的 然后,您可以在then()块中对其进行更改,并且更改仍将在then()

之外生效。

工作示例如下:

   $scope.newPost.content = "Part 2 of phrase";
    Phrase.get({id: $scope.newPost.phrase_id}).$promise.then(function(result){
        $scope.newPost.content = result.content + " " + $scope.newPost.content; 
    });

    console.log($scope.newPost.content)