【问题标题】:MEAN Stack application: Toggle boolean valueMEAN Stack 应用程序:切换布尔值
【发布时间】:2017-06-26 14:58:01
【问题描述】:

我正在使用 mlab 和 mongojs 以及 Angular。当我尝试切换布尔值 (onStatus) 时,视图中的按钮会从关闭切换到打开,但它会使应用程序崩溃。当我签入数据库时​​,该属性已从文档中删除。代码如下:sn-ps:

device.service.ts

toggleDevice(updatedStatus){
var headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.put('/api/device/'+updatedStatus._id,   JSON.stringify(updatedStatus), {headers: headers})
  .map(res => res.json());
}

devices.component.ts

toggleDevice(device){
var currentStatus = device.onStatus;
var updatedStatus = {
  _id: device._id,
  name: device.name,
  onStatus: !currentStatus
};

this.deviceService.toggleDevice(updatedStatus)
  .subscribe(data => {
    device.onStatus = !device.onStatus
  });

}

devices.compoonents.html

<button class="btn" (click)="toggleDevice(device)" type="button">{{ device.onStatus ? 'Switch Off' : 'Switch On' }}</button>

API 路由

var express = require('express');
var router  = express.Router();
var database = require('../config/database');
var mongojs = require('mongojs');
var db      = mongojs(database.url, ['devices'])

// GET : All devices
router.get('/devices', function(req, res, next){
  db.devices.find(function(err, devices){
    if(err) {
      res.send(err);
    }
    res.json(devices);
  });
});

// GET : Single device
router.get('/device/:id', function(req, res, next){
  db.devices.findOne({_id: mongojs.ObjectId(req.params.id)}, function(err, device){
    if(err) {
      res.send(err);
    }
    res.json(device);
  });
});

// POST : Save a device
router.post('/device', function(req, res, next){
  var device = req.body;
  device.onStatus = false;
  if(!device.name) {
      res.status(400);
      res.json({
        "error": "Please add a name."
      });
  } else {
    db.devices.save(device, function(err, device){
      if(err) {
        res.send(err);
      }
      res.json(device);
    });
  }
});

// DELETE : A device
router.delete('/device/:id', function(req, res, next){
  db.devices.remove({_id: mongojs.ObjectId(req.params.id)}, function(err, device){
    if(err) {
      res.send(err);
    }
    res.json(device);
  });
});

// PUT : Update a device
router.put('/device/:id', function(req, res, next){
  var device = req.body;
  var updatedDevice = {};

  if(device.name) {
    updatedDevice.name = device.name;
  }

  if(!updatedDevice){
    res.status(400);
    res.json({'Error': 'Name not specified'});
  } else {
    db.devices.update({_id: mongojs.ObjectId(req.params.id)}, updatedDevice, {}, function(err, device){
      if(err) {
        res.send(err);
      }
      res.json(device);
    });
  }
  db.devices.findOne({_id: mongojs.ObjectId(req.params.id)}, function(err, device){
    if(err) {
      res.send(err);
    }
    res.json(device);
  });
});

module.exports = router;

错误

/home/chopin/Development/homeautomation/node_modules/mongojs/node_modules/mongodb/lib/utils.js:98
    process.nextTick(function() { throw err; });
                                  ^

Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
    at ServerResponse.header (/home/chopin/Development/homeautomation/node_modules/express/lib/response.js:719:10)
    at ServerResponse.send (/home/chopin/Development/homeautomation/node_modules/express/lib/response.js:164:12)
    at ServerResponse.json (/home/chopin/Development/homeautomation/node_modules/express/lib/response.js:250:15)
    at /home/chopin/Development/homeautomation/routes/devices.js:80:9
    at /home/chopin/Development/homeautomation/node_modules/mongojs/lib/collection.js:50:5
    at handleCallback (/home/chopin/Development/homeautomation/node_modules/mongojs/node_modules/mongodb/lib/utils.js:95:56)
    at /home/chopin/Development/homeautomation/node_modules/mongojs/node_modules/mongodb/lib/cursor.js:674:5
    at handleCallback (/home/chopin/Development/homeautomation/node_modules/mongojs/node_modules/mongodb/node_modules/mongodb-core/lib/cursor.js:171:5)
    at nextFunction (/home/chopin/Development/homeautomation/node_modules/mongojs/node_modules/mongodb/node_modules/mongodb-core/lib/cursor.js:682:5)
[nodemon] app crashed - waiting for file changes before starting...

感谢您的帮助。

编辑:我应该提到该错误仅在我第二次切换按钮时发生。我假设由于某种原因这已从数据库中删除。名称和 ID 保持不变,但 onStatus 不会。

编辑2:完整代码https://github.com/Sacki2013/homeAutomation

【问题讨论】:

    标签: javascript angularjs node.js mongoose mongojs


    【解决方案1】:

    您正在尝试发送响应,即使它已经发送。您所要做的就是在发送回复后添加return 语句。

    var express = require('express');
    var router  = express.Router();
    var database = require('../config/database');
    var mongojs = require('mongojs');
    var db      = mongojs(database.url, ['devices'])
    
    // GET : All devices
    router.get('/devices', function(req, res, next){
      db.devices.find(function(err, devices){
        if(err) {
          res.send(err);
          return;
        }
        res.json(devices);
      });
    });
    
    // GET : Single device
    router.get('/device/:id', function(req, res, next){
      db.devices.findOne({_id: mongojs.ObjectId(req.params.id)}, function(err, device){
        if(err) {
          res.send(err);
          return;
        }
        res.json(device);
     });
    });
    
    // POST : Save a device
    router.post('/device', function(req, res, next){
      var device = req.body;
      device.onStatus = false;
      if(!device.name) {
        res.status(400);
        res.json({"error": "Please add a name."});
      } else {
        db.devices.save(device, function(err, device){
          if(err) {
            res.send(err);
            return;
          }
          res.json(device);
        });
      }
    });
    
    // DELETE : A device
    router.delete('/device/:id', function(req, res, next){
      db.devices.remove({_id: mongojs.ObjectId(req.params.id)}, function(err, device){
        if(err) {
          res.send(err);
          return;
        }
        res.json(device);
     });
    });
    
    // PUT : Update a device
    router.put('/device/:id', function(req, res, next){
      var device = req.body;
      var updatedDevice = {};
    
      if(device.name) {
        updatedDevice.name = device.name;
      }
    
      if(!updatedDevice){
        res.status(400);
        res.json({'Error': 'Name not specified'});
      } else {
        db.devices.update({_id: mongojs.ObjectId(req.params.id)}, updatedDevice, {}, function(err, device){
          if(err) {
            res.send(err);
            return;
          }
          /*
           * Commenting following line because
           * you are sending a response in `findOne` 
           */ 
          // res.json(device);
          db.devices.findOne({_id: mongojs.ObjectId(req.params.id)}, function(err, device){
            if(err) {
              res.send(err);
              return;
            }
            res.json(device);
          });
        });
       }
      });
    
      module.exports = router;
    

    【讨论】:

    • 修复它太棒了。好吧,并添加 updatedDevice.onStatus = device.onStatus;到 PUT 请求。感谢您对 RETURN 语句的帮助。
    • 当然,我很乐意提供帮助。
    【解决方案2】:

    在您的 /device/:id PUT 端点上,您正在异步执行 update 和 findOne 调用,彼此独立,因此 res.json() 被调用两次。尝试在 update 回调中移动您的 findOne 函数。

    【讨论】:

    • 您对导致错误的原因是正确的。我删除了查找代码并删除了错误。我仍然无法切换布尔值,但在下一次切换时不会将其删除。
    • 谢谢。我现在已经开始工作了。这是服务器排序。是时候在 C 中尝试客户端了。:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-19
    • 2020-10-07
    • 2017-09-08
    • 2020-12-20
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多