简体   繁体   English

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

[英]How to refresh client side value when meteor method throws an error?

I wrote a Meteor method for changing an object. 我写了一个改变对象的Meteor方法。 Only the owner of the object should be able to edit properties. 只有对象的所有者才能编辑属性。

The method thus checks for a match of the current user and the object owner. 该方法因此检查当前用户和对象所有者的匹配。 If it doesn't match, the method throws an exception with the cause. 如果它不匹配,则该方法抛出原因的异常。

This approach works, as the change does not hit the collection and the error object is returned to the client. 此方法有效,因为更改未触及集合,并且错误对象将返回给客户端。

Nevertheless the edited property is not updated to reflect it's actual value. 然而,编辑后的财产未更新以反映其实际价值。 How can I trigger refreshing the value? 如何触发刷新值?

Additional info: I am using React on the frontend; 附加信息:我在前端使用React; the object is not updated explicitely in the frontend code (so the method seems to be run on the client side, too). 该对象未在前端代码中明确更新(因此该方法似乎也在客户端运行)。

Some code (simplified, naming changed, obvious errors might not be in the original ;) 一些代码(简化,命名改变,明显的错误可能不在原文中;)

Client side: 客户端:

  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.");
      }
    });
  }

Server Side: 服务器端:

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});
    }
  }

To refresh in the client side after update: 更新后在客户端刷新:

  1. Make sure you publish the data on the server and then add to constructor in controller - this.subscribe('Comments'); 确保在服务器上发布数据,然后添加到控制器中的构造函数 - this.subscribe('Comments'); See the example below in AngularJS 请参阅AngularJS中的以下示例
  2. Once the server updates, the comments should update. 服务器更新后,评论应该更新。 You may also need to run meteor remove autopublish for the front end to update correctly. 您可能还需要运行meteor remove autopublish以使前端正确更新。 The meteor server prompted me to do this 流星服务器促使我这样做

In your case, the comments won't be filtered and you can filter the update based on the comment ID and the user. 在您的情况下,不会过滤注释,您可以根据注释ID和用户过滤更新。 If no already existing comment is found, then the update will not work and you can catch throw an error. 如果没有找到已存在的注释,则更新将不起作用,您可以捕获抛出错误。

  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;
    }
);

imports/component/stocks/stocks.html 进口/组件/股/ 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>

imports/component/stocks/stocks.js 进口/组件/股/ 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]
});

imports/api/UserStocks.js 进口/ 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;
  }
});

server/main.js 服务器/ main.js

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从 meteor 方法的服务器端抛出错误时,无法在客户端捕获 Meteor.Error - cannot catch Meteor.Error in client when error thrown from server side of meteor method 如何从Meteor Shell更改客户端变量的值? - How to change the value of a client-side variable from the Meteor shell? Meteor:客户端调用服务器端方法 - Meteor: Call server-side method by client 流星:粘贴事件(客户端)以调用流星方法 - METEOR: Paste event (client side) to call meteor method 我如何捕获并将Meteor.Error警报从Meteor.Methods插入客户端数据库? - how i catch and insert Meteor.Error alerts From Meteor.Methods in to a client side db? 流星服务器在流星方法中使用 Accounts.addEmail() 引发错误 - Meteor server throws error with Accounts.addEmail() in a meteor method 流星在调用服务器端方法中的错误句柄 - Error handle in Meteor in calling server side method 如何获取在Meteor上的客户端的subscription方法上发布的数据? - How do I get the data published at client-side's subscribe method on Meteor? 在方法流星中将值服务器传递给客户端 - passing value server to client in method meteor 如何在客户端流星中使用自动格式化中的正则表达式来验证字段的输入值? - How to validate a field's input value using regular expression in autoform in meteor on client side?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM