postman POST请求正确填充数据库,但在写入文件

时间:2017-08-03 14:27:40

标签: node.js mongodb express postman mongoose-schema

我的一个节点控制器遇到了一个奇怪的问题。对于上下文,在针对此特定控制器的POST请求中,我将对象存储在mongo数据库中,并将对象的必要部分写入文件。有一个已经存在的网站,它直接与服务器连接,但我正在为想要自定义界面的客户编写REST api。 (我没有写节点服务器或网站。)

我的问题是,出于某种原因,在这种情况下写入文件的值在“post”之后显示为Null,如下所示:     { “腿”:[{ “PTU”:{ “倾斜”:{}, “PAN”:{}}},{ “音频”:{ “静音”:假, “体积”:0}, “PTU” :{ “倾斜”:{ “ABS”:NULL} “锅”:{ “ABS”:空}}},{ “音频”:{ “静音”:真, “体积”:0}, “PTU” :{ “倾斜”:{ “ABS”:NULL} “锅”:{ “ABS”:空}}}]}

但是,网站上的表格填写正确,如果我从网站上按“保存”,文件就会正确更新。即。

{"legs":[{"ptu":{"tilt":{"abs":0},"pan":{"abs":0}}},{"audio":{"track":"/home/rahd/ult0316-p002/resources/tracks/Maid with the Flaxen Hair.mp3","vol":0,"mute":false},"ptu":{"tilt":{"abs":10},"pan":{"abs":10}}},{"audio":{"track":null,"vol":0,"mute":true},"ptu":{"tilt":{"abs":10},"pan":{"abs":10}}}]}

这是我的邮递员请求,它以原始JSON格式发送:

{        
    "name": "NicksCoolTour3",
    "location": "/home/rahd/ult0316-p002/resources/tours/5982374cb492c516c20c40d0.json",
    "legs": [
        {
                "audio": {
                "mute": true,
                "volPercent": 0,
                "vol": -120,
                "track": null
            },
            "ptu": {
                "poi": "59823726b492c516c20c40cd",
                "tilt": {
                    "vel": 5,
                    "rel": 0,
                    "abs": 0
                },
                "pan": {
                    "vel": 5,
                    "rel": 0,
                    "abs": 0
                },
                "direction": "quickest"
            },
            "time": 0,
            "velMode": "time",
            "ptuMode": "poi"
        },
        {
            "_id": "5982374cb492c516c20c40d2",
            "audio": {
                "mute": false,
                "volPercent": 100,
                "vol": -120,
                "track": "5983222d79930a1dbd4d94ac"
            },
            "ptu": {
                "tilt": {
                    "vel": 5,
                    "rel": 10,
                    "abs": 0
                },
                "pan": {
                    "vel": 5,
                    "rel": 10,
                    "abs": 0
                },
                "direction": "quickest"
            },
            "time": 0,
            "velMode": "time",
            "ptuMode": "rel"
        },
        {
            "_id": "5982374cb492c516c20c40d1",
            "audio": {
                "mute": true,
                "volPercent": 100,
                "vol": -120,
                "track": "59823711b492c516c20c40cc"
            },
            "ptu": {
                "tilt": {
                    "vel": 5,
                    "rel": 0,
                    "abs": 0
                },
                "pan": {
                    "vel": 5,
                    "rel": 0,
                    "abs": 0
                },
                "direction": "quickest"
            },
            "time": 0,
            "velMode": "time",
            "ptuMode": "rel"
        }
    ]
}

这是我的POST控制器:

  router.post('/',function (req, res, next){
    var new_tour = new Tour(req.body);
    new_tour._id = new mongoose.Types.ObjectId;
    new_tour.save( function(err, tour) {
      if (err) return next(err);
      res.json({ message: "tours database sucessfully updated" });
    });
  });

我不确定是什么导致这种情况,似乎数据库正在获取正确的值,但将请求写入文件的函数行为不正常。

这是处理文件写入的模式:

var mongoose = require("mongoose")
    , fs = require('fs')
    , path = require('path')
    , resources = require(path.join(__dirname, '..', '..', 'config', 'resources'));

var schema = new mongoose.Schema({
    name: { type: String, default: '', unique: true, required: true },
    location: { type: String },
    legs: [{
        ptuMode: { type: String, default: 'abs' }, // abs || rel || poi
        velMode: { type: String, default: 'vel' }, // vel || time
        time: { type: Number, default: 0 }, // vel || time
        ptu: {
            direction: { type: String, default: 'cw' }, // cw || ccw
            pan: {
                rel: { type: Number },
                abs: { type: Number },
                vel: { type: Number },
            },
            tilt: {
                rel: { type: Number },
                abs: { type: Number },
                vel: { type: Number },
            },
            poi: {
                type: mongoose.Schema.Types.ObjectId,
                ref: 'POI'
            },
        },
        audio: {
            mute: { type: Boolean },
            vol: { type: Number },
            volPercent: { type: Number },
            track: {
                type: mongoose.Schema.Types.ObjectId,
                ref: 'Track'
            },
        }
    }]
},
    {
        timestamps: true
    });

schema.pre('save', function (next) {
    var tour = this;
    if (!tour.location || tour.location.length < 1) {
        tour.location = path.join(resources.tours, tour._id + '.json');
    }

    tour.writeToFile(function (err) {
        console.error(err);
    });

    next();
});

schema.post('remove', function (tour) {
    if (tour.location && tour.location.length > 0) {
        fs.exists(tour.location, function (exists) {
            if (exists) {
                fs.unlink(tour.location);
                console.log('Deleted Tour: ' + tour.location);
            } else {
                console.log('Tour not found, so not deleting file.');
            }
        });
    }
});

schema.methods.writeToFile = function (callback) {

    function saveToFile(tour, callback) {
        var filePath = tour.location;
        var name = tour.name;
        delete tour.location;
        delete tour.name;
        delete tour.createdAt;
        delete tour.updatedAt;
        delete tour._id;
        delete tour.__v;

        for (li in tour.legs) {
            var leg = tour.legs[li];
            var index = li;
            if (typeof index === 'string') {
                index = parseInt(li);
            }

            delete leg._id;

            // Delete rel, force abs
            delete leg.ptu.tilt.rel;
            delete leg.ptu.pan.rel;

            if (leg.audio.hasOwnProperty("volPercent")) {
                var x = leg.audio.volPercent;
                delete leg.audio.volPercent;
                var n = -120;
                if (x > 0) {
                    var val = Math.pow((x / 100), 4);
                    n = Math.max(20 * Math.log10(val), -120)
                }
                leg.audio.vol = n;
            }

            if (index == 0) {
                delete leg.ptu.pan.vel;
                delete leg.ptu.tilt.vel;

            } else {
                if (leg.ptu.pan.vel == 0) {
                    leg.ptu.pan.vel = 50;
                }

                if (leg.ptu.tilt.vel == 0) {
                    leg.ptu.tilt.vel = 50;
                }

                if (leg.ptu.direction === 'ccw') {
                    leg.ptu.pan.vel = -(Math.abs(leg.ptu.pan.vel));
                }
            }

            if (leg.ptu.direction === 'quickest') {
                delete leg.ptu.tilt.vel;
                delete leg.ptu.pan.vel;
            }

            if (typeof (leg.audio.track) === 'object' && leg.audio.track !== null) {
                leg.audio.track = leg.audio.track.location;
            }

            // Handle Delay
            if (leg.ptuMode == 'delay') {
                delete leg.ptu.pan;
                delete leg.ptu.tilt;
            } else {
                delete leg.ptu.delay;
            }

            delete leg.ptu.poi;
            delete leg.time;
            delete leg.ptu.direction;
            delete leg.ptuMode;
            delete leg.velMode;
            if (index == 0) {
                delete leg.audio;
            }
        }

        if (filePath && filePath.length > 0) {
            fs.writeFile(filePath, JSON.stringify(tour), function (err) {
                if (err) {
                    if (callback) callback(err);
                    return console.error(err);
                }
                console.log("Tour Written: " + name);
            });
        } else {
            console.error("Tour location empty: " + name);
        }

    }

    var tour = this.prepareExport();

    saveToFile(tour, callback);
};

schema.methods.prepareExport = function () {
    // TODO: Ensure Track and POI are loaded
    var tour = this.toObject();
    var prevLeg = false;

    // Calculate proper abs positions before prepare for export
    for (li in tour.legs) {
        var leg = tour.legs[li];
        if (leg.ptuMode == 'poi') {
            leg.ptu.pan.abs = leg.ptu.poi.pan;
            leg.ptu.tilt.abs = leg.ptu.poi.tilt;
        } else if (leg.ptuMode == 'rel' && prevLeg) {
            leg.ptu.pan.abs = prevLeg.ptu.pan.abs + leg.ptu.pan.rel;
            leg.ptu.tilt.abs = prevLeg.ptu.tilt.abs + leg.ptu.tilt.rel;
        }
        if (leg.ptuMode !== 'delay') {
            prevLeg = leg;
        }
    }

    // Calulcate degrees per second for each leg
    prevLeg = false;
    for (li in tour.legs) {
        var leg = tour.legs[li];
        if (prevLeg && leg.velMode == 'time') {
            var time = Math.abs(leg.time) || 0;
            if (time > 0) {
                if (leg.ptuMode == 'delay') {
                    leg.ptu.delay = time;
                } else if (leg.ptuMode == 'rel') {
                    leg.ptu.pan.vel = leg.ptu.pan.rel / time;
                    leg.ptu.tilt.vel = leg.ptu.tilt.rel / time;
                } else {
                    leg.ptu.pan.vel = (leg.ptu.pan.abs - prevLeg.ptu.pan.abs) / time;
                    leg.ptu.tilt.vel = (leg.ptu.tilt.abs - prevLeg.ptu.tilt.abs) / time;
                }
            } else {
                leg.ptu.pan.vel = 0;
                leg.ptu.tilt.vel = 0;
            }

            leg.ptu.pan.vel = Math.abs(leg.ptu.pan.vel);
            leg.ptu.tilt.vel = Math.abs(leg.ptu.tilt.vel);

            if (leg.ptu.direction === 'ccw') {
                leg.ptu.pan.vel = -leg.ptu.pan.vel;
            }

            // Vel bounds
            if (leg.ptu.pan.vel > 50) {
                leg.ptu.pan.vel = 50;
            } else if (leg.ptu.pan.vel < 5 && leg.ptu.pan.vel > 0) {
                leg.ptu.pan.vel = 5;
            }
            if (leg.ptu.tilt.vel > 50) {
                leg.ptu.tilt.vel = 50;
            } else if (leg.ptu.tilt.vel < 5 && leg.ptu.tilt.vel > 0) {
                leg.ptu.tilt.vel = 5;
            }

            // Quickest was using 50ยบ/s, but should be omitted
            if (leg.ptu.direction === 'quickest' && time === 0) {
                delete leg.ptu.pan.vel;
                delete leg.ptu.tilt.vel;
            }

            // Remove invalid tilt velocity when tilt diff is 0 so vector vel on control server is calculated correctly
            if (prevLeg.ptu.tilt.abs - leg.ptu.tilt.abs == 0) {
                delete leg.ptu.tilt.vel;
            }
        }
        prevLeg = leg;
    }
    return tour;
};

/* bounds logic

if (leg.ptu.pan.abs > 180) {
    leg.ptu.pan.abs = leg.ptu.pan.abs - 360;
} else if (leg.ptu.pan.abs < -180) {
    leg.ptu.pan.abs = leg.ptu.pan.abs + 360;
}

if (leg.ptu.tilt.abs > 90) {
    leg.ptu.tilt.abs = 90;
} else if (leg.ptu.tilt.abs < -90) {
    leg.ptu.tilt.abs = -90;
}
*/

var Tour = mongoose.model("Tour", schema);

module.exports = Tour;

1 个答案:

答案 0 :(得分:1)

您的异步功能出错:

schema.pre('save',function(next),next必须在回调函数中

tour.writeToFile(function (err) {
    console.error(err);
    next();
});

schema.methods.writeToFile = function(callback):您必须在成功时返回回调,而不仅仅是在错误

    if (filePath && filePath.length > 0) {
        fs.writeFile(filePath, JSON.stringify(tour), function (err) {
            if (err) {
                if (callback) callback(err);
                return console.error(err);
            }
            else
            {
                console.log("Tour Written: " + name);
                if (callback) callback(err);
            }

        });
    } else {
        console.error("Tour location empty: " + name);
         if (callback) callback(err);
    }