2017-02-08 1 views
0

Ich benutze Mlab und Mongojs zusammen mit Angular. Wenn ich versuche, einen booleschen Wert (onStatus) umzuschalten, schaltet die Schaltfläche in der Ansicht von "Aus" auf "Ein" um, stürzt jedoch die App ab. Beim Einchecken der DB wurde die Eigenschaft aus dem Dokument entfernt. Code-Schnipsel unten:MEAN Stack-Anwendung: Toggle booleschen Wert

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 Routing

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; 

Fehler

/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... 

Vielen Dank für jede Hilfe.

EDIT: Ich sollte erwähnen, der Fehler tritt nur das zweite Mal auf, ich schalte den Knopf. Ich gehe davon aus, dass dies aus irgendeinem Grund aus der DB entfernt wurde. Der Name und die ID bleiben erhalten, der onStatus jedoch nicht.

EDIT 2: Voll Code https://github.com/Sacki2013/homeAutomation

Antwort

0

Sie versuchen, die Antwort zu senden, auch nachdem sie bereits gesendet wurde. Alles, was Sie tun müssen, ist, dass Sie return Anweisungen hinzufügen, nachdem Ihre Antwort gesendet wurde.

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; 
+0

Ehrfürchtig, dass es behoben. Nun, dass und Hinzufügen der updatedDevice.onStatus = device.onStatus; auf die PUT-Anfrage. Vielen Dank für die Hilfe, mit den Anweisungen RETURN. – user2682597

+0

Sicher, ich bin glücklich helfen. –

0

Auf Ihrem /device/:idPUT Endpunkt tun Sie die update und findOne Anrufe asynchron, unabhängig voneinander, so res.json() zweimal aufgerufen wird. Versuchen Sie, Ihre findOne Funktion in den update Rückruf zu verschieben.

+0

Sie haben damit den Fehler verursacht. Ich habe den Fundcode entfernt und den Fehler behoben. Ich kann den booleschen Wert immer noch nicht umschalten, ohne dass er beim nächsten Wechsel entfernt wird. – user2682597

+0

Ich sehe, du hast es schon funktioniert, oder? –

+0

Danke. Ich habe es jetzt funktioniert. Das ist der Server sortiert. Zeit, um den Client in C. versuchen :( – user2682597

Verwandte Themen