【问题标题】:Http request service with Angular throwing an errorAngular 的 Http 请求服务引发错误
【发布时间】:2015-08-06 18:38:33
【问题描述】:

我正在尝试编写一个服务,向我的路由 (NodeJs) 发出 http 请求以将用户添加到数据库。

如果我只是将它写在控制器中它可以工作,但是在我刷新浏览器之前你不会看到添加的用户:

我在控制器中的代码:

//Function to add a user to the db
$scope.inviteUser = function(){
    $http.post('/api/users/invite', {
        'email': $scope.user.email,
        'role_id': $scope.user.role
    }, {
        headers: {
            "Content-Type": "text/plain"
        }
    })
    .success(function(data, status, headers, config) {
        console.log("Successfully saved a user to the DB", data);

        $scope.userInfo.push(data);


    })
    .error(function(data, status, headers, config) {
        console.log("Failed to add user to DB");
    });
}

我在服务中需要它的原因是因为堆栈上的人告诉我它会解决我目前面临的问题,即当添加用户时,在刷新浏览器之前你不会看到它。这是因为我有一个带有按钮邀请的视图,当您单击它时会显示一个弹出窗口(md-dialog -> angular material)。这个对话框有它自己的 tmple.html 文件。在邀请按钮所在的视图中是链接到的 $scope.userInfo(在函数inviteUser - 上面的代码中定义)

带有邀请按钮的视图代码和添加用户的列表:

<div id="sidebar" class="md-whiteframe-z4" ng-data-color="">
      <div style="height: 80px;"></div>
      <div class="userList">
        <li id="customLI" ng-repeat="user in userInfo" id="userPos" class="circular md-whiteframe-z2" style="background-color: {{ user.color }} " ng-click=" showPopUpDeletionConfirmation(); setDeleteId( user._id )" ng-data-id="{{ user._id }} ">
          <p class="initials" id="userValue" style="top: {{ user.top }};" >
              <custom id="user._id"></custom>
              {{user.initials}}
          </p>
        <md-tooltip>
        <!-- Delete this user -->  {{user.name}}
        </md-tooltip>
        </li>
      </div>
    </div>

对话框代码:

  <md-dialog aria-label="" ng-controller="CalendarCtrl">
    <form name="form"  >
      <md-toolbar>
        <div class="md-toolbar-tools">
          <h1 class="customH1">Invite a user</h1>

          <span flex></span>
          <!-- <md-button class="md-icon-button" ng-click="closeDialog()">
            <md-icon md-svg-src="images/ic_close_24px.svg" aria-label="Close dialog"></md-icon>
          </md-button> -->
        </div>
      </md-toolbar>
      <md-dialog-content>
        <div id="containerForm">
            <div layout="row">
              <md-input-container flex="">
                <div class="form-group" ng-class="{ 'has-success': form.email.$valid && submitted,'has-error': form.email.$invalid && submitted }">
                  <label>Enter the user's e-mail</label>
                  <input type="email" name="email" id="to" class="form-control" ng-model="user.email" required mongoose-error/>
                  <p class="help-block" ng-show="form.email.$error.email && submitted">
                    Doesn't look like a valid email.
                  </p>
                  <p class="help-block" ng-show="form.email.$error.required && submitted">
                    What's your email address?
                  </p>
                  <p class="help-block" ng-show="form.email.$error.mongoose">
                    {{ errors.email }}
                  </p>
                </div>
              </md-input-container>
            </div>  

            <br /><br />

            <div ng-show="form.email.$dirty && form.email.$valid">
              <h5>Assign one of the following role's:</h5>

              <div id="wrapperRadioButtons">
                <md-radio-group ng-model="user.role">
                  <md-radio-button ng-repeat="userrole in roleInfo" value="{{userrole.id}}" class="md-primary">{{userrole.role}}</md-radio-button>
                </md-radio-group>
              </div>
              </div>

            <br />

        </div>
      </md-dialog-content>
      <div class="md-actions" layout="row" >
        <md-button ng-click="closeDialog()" class="md-primary">Cancel</md-button>

        <md-button id="send_email" ng-click="inviteUser(); closeDialog()" class="md-primary">Invite</md-button>
      </div>
    </form>
  </md-dialog>

这是我编写并尝试链接到函数inviteUsers的服务:

zazzleApp.factory('UserService', ['$q', '$http', function ($q, $http) {
            var service = {};

            service.get = function() {
              var deferred = $q.defer();

              deferred.resolve(service.data);
              return deferred.promise;
            }

            service.save = function(data) {
                var promise = $http({
                    method: 'POST',
                    url: 'api/users/invite'
                })

                var deferred = $q.defer();

                service.data.push(data);
                deferred.resolve();
                return deferred.promise;
            }

            return service;
        }
    ]);

我的控制器的一部分:

angular.module('zazzleToolPlannerApp')
    .controller('CalendarCtrl', function ($scope, $mdDialog, $http, $rootScope, $timeout, User, Auth, UserService) {

        //Function to add a user to the db
        $scope.inviteUser = function(){

           var obj = {
                'email': $scope.user.email,
                'role_id': $scope.user.role
           };
           UserService.save(obj).then(function(){
                $scope.getUsers();

           })
        }
});

现在,当我尝试添加用户时,我的控制台中出现错误 -> https://gyazo.com/34b39d7eda18b8afd9ef11094b4f429a

所以基本上我要问的是如何编写一个发出 http 请求并将其链接到控制器的服务....

旁注:我以前从未这样做过,所以这就是为什么它可能不起作用。

【问题讨论】:

    标签: javascript angularjs node.js angular-material


    【解决方案1】:

    我只能看到你的日志里写着

    typeError 无法读取 object.service.save 中未定义的属性 'push'

    我认为这与您的 HTTP 请求无关。 你还没有定义你的service.data.push(data);,这就是他转储的地方

    尝试将service 对象的data 属性定义为数组,然后再将值推送给它(它还不知道它是一个数组,因此它无法访问数组原型函数)

    这样做

    service = { data: [] };
    

    希望这会有所帮助。

    【讨论】:

    • 是的,解决了这个问题,但是我得到了另一个错误。我主要喜欢博世所说的话,但我仍在等待他的小提琴......
    【解决方案2】:

    您在控制台中收到错误的原因是service.data.push(data); 中的service.data 不存在。您的意思可能是将新用户推入尚未创建的用户数组中(您似乎对代码中的“数据”感到困惑:P)。

    无论如何,您的问题的解决方案要简单得多: 在服务中,您可以将 $http.post() 返回到控制器并在控制器中处理 .success() 回调中的请求。此外,您需要更新的用户列表应该驻留在服务中,并且您可以从控制器绑定到它;这样,它会在您添加新用户后保持模板更新,而无需刷新浏览器。您只需从服务中检索 $http 回调中的用户列表。

    如果你仍然觉得这令人困惑,我可以写一个小提琴。

    编辑:这里是小提琴:http://jsfiddle.net/bosch/8pnL23k7/。希望它能帮助您更好地理解这些概念

    【讨论】:

    • 这是您的小提琴jsfiddle.net/bosch/8pnL23k7,希望对您有所帮助。对不起,它看起来很糟糕,我很着急。如果仍然不清楚,请随时询问。
    • 嗯,我在我的代码上使用了你的小提琴。当应用程序加载时,现有用户并没有加载,当我邀请用户时,我得到以下错误 - > gyazo.com/a25b69283865228714024b1e436942f2
    • 从错误看来,您没有将服务的承诺返回给控制器。确保在 AddUser 方法中的 $http 之前使用关键字“return”
    • 更新,我现在可以将用户保存到数据库,但我无法读出用户...
    • 保存用户后不要忘记调用该方法来检索用户列表:在 .success() 上,您应该调用 UserService.getUsers() 或该方法的名称
    猜你喜欢
    • 2018-04-17
    • 2018-11-28
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 2021-10-03
    相关资源
    最近更新 更多