当meteor方法抛出错误时如何刷新客户端值?

时间:2017-01-23 14:56:59

标签: javascript meteor

我写了一个改变对象的Meteor方法。只有对象的所有者才能编辑属性。

该方法因此检查当前用户和对象所有者的匹配。如果它不匹配,则该方法抛出原因的异常。

此方法有效,因为更改未命中集合,并且错误对象将返回给客户端。

尽管如此,编辑后的财产并未更新以反映其实际价值。如何触发刷新值?

其他信息:我在前端使用React;该对象未在前端代码中明确更新(因此该方法似乎也在客户端运行)。

有些代码(简化,命名已更改,明显的错误可能不在原文中;)

客户端:

  saveCommentChanges(updatedComment) {
    Meteor.call('comment.updateComment', updatedComment, function (error, result) {
      if (error && error.error === "not-authorized") {
            Session.set("errorMessage", "You are only allowed to change own comments.");
      }
    });
  }

服务器端:

if (Meteor.isServer) {  
  Meteor.methods({
    'comment.updateComment'(comment) {
    check(comment, Object);

    origComment = Comments.findOne(comment._id);

    if (origComment.user != this.userId) {
      console.log('user does not match');
      throw new Meteor.Error('not-authorized');
    }

    let res = Comments.update(
      {'_id': comment._id},
      {$set: {date: comment.date,
          comment: comment.comment}
      }, {removeEmptyStrings: false});
    }
  }

1 个答案:

答案 0 :(得分:0)

更新后在客户端刷新:

  1. 确保在服务器上发布数据,然后添加到控制器中的构造函数 - this.subscribe('Comments'); 请参阅AngularJS中的以下示例
  2. 服务器更新后,评论应更新。您可能还需要为前端运行meteor remove autopublish才能正确更新。流星服务器促使我这样做
  3. 在您的情况下,评论不会被过滤,您可以根据评论ID和用户过滤更新。如果找不到已存在的注释,则更新将不起作用,您可以发现错误。

      if (Meteor.isServer) { 
    // This code only runs on the server
          Meteor.publish('comments', function publishComments() {
            return Comments.find({});
          });
      }
    
      Meteor.methods({
        'comment.updateComment'(comment) {
        check(comment, Object);
    
        origComment = Comments.findOne(comment._id);
    
    // option 1
        if (origComment.user != this.userId) {
          console.log('user does not match');
          throw new Meteor.Error('not-authorized');
        }
    
    // keep the same update here
    
    // option 2
        let res = Comments.update(
           { '_id': comment._id,'user': origComment.user},
          {$set: {date: comment.date,
              comment: comment.comment}
          }, {removeEmptyStrings: false});
          return res;
        }
    );
    

    <强>进口/组件/股/ stocks.html

    <button type="submit" class="btn btn-success btn-sm m-2" 
    ng-hide="{{$ctrl.currentUser === null}}"
    ng-click="$ctrl.buyStock(stock.name, 1)">
       Buy 1 Share
    </button>
    

    <强>进口/组件/股/ stocks.js

    import angular from 'angular';
    import angularMeteor from 'angular-meteor';
    import template from './stocks.html';
    
    import { Meteor } from 'meteor/meteor';
    import { Stocks } from '../../api/Stocks.js';
    import { UserStocks } from '../../api/UserStocks.js';
    
    class StocksCtrl {
    
      constructor($scope) {
        $scope.viewModel(this);
    
        this.subscribe('stocks');
        this.subscribe('userStocks');
    
        // Return the data mostly right now
        this.helpers({
          currentUser() {
            return Meteor.user();
          },
          stocks() {
            const selector = {};
            // Show newest tasks at the top
            return Stocks.find(selector, {
              sort: {
                name: 1
              }
            });
          },
          userStocks() {
            return UserStocks.find({});
          }
        })
      }
    
      buyStock(stock, amt) {
        console.log("Buying stock processing...");
    
        // ADD TO UserStock
        Meteor.call('userStocks.buy', stock, amt, function(error, result) {
          if(error){
            console.log(error.reason);
            return;
          } 
          // log to console
          console.log("UserID: " + Meteor.userId() + "\n Username: " + Meteor.user().username 
            + "\n Message: Purchase of " + amt + " shares of " + stock + " was successful.");
    
          // alert the user
          alert("Purchase of " + amt + " shares of " + stock + " was successful.");
        });
        console.log("Buying stock complete.");
      }
    
    }
    
    export default angular.module('StocksApp', [
      angularMeteor
    ])
    .component('stocksApp', {
      templateUrl: 'imports/components/stocks/stocks.html',
      controller: ['$scope', StocksCtrl]
    });
    

    <强>进口/ API / UserStocks.js

    import { Meteor } from 'meteor/meteor';
    import { Mongo } from 'meteor/mongo';
    
    export const UserStocks = new Mongo.Collection('userStocks');
    
    
    if (Meteor.isServer) {
      // This code only runs on the server
      // Only publish tasks that are public or belong to the current user
      Meteor.publish('userStocks', function getUserStocks() {
        return UserStocks.find({
            ownerID: { $eq: this.userId }
          });
      });
    }
    
    Meteor.methods({
      'userStocks.buy' (stock, amount) {
        // Make sure the user is logged in before inserting a task
        if (!Meteor.userId()) {
          throw new Meteor.Error('not-authorized');
        }
    
        // if currently exists, increase the amount by the amount purchased
        // if it does not exit, the upsert true will create/insert
        const newID = UserStocks.update(
          { ownerID: { $eq: this.userId }, stock: { $eq: stock } },
          { $setOnInsert: { ownerID: this.userId, stock: stock}, $inc: {amt: amount} },
          { upsert: true, returnNewDocument: true}
        );
    
        return newID;
      }
    });
    

    服务器/ main.js

    import '../imports/api/Stocks.js';
    import '../imports/api/UserStocks.js';