2

I have been having an very odd issue and I think it might be the way I am doing nested levels in the mongoose schema. First lets get the schema:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var RLSchema = new Schema({
    user_id: { type: String, required: true },
    coordinate: {
        accuracy: Number,
        latitude: Number,
        longitude: Number
    },
    agency_id: String,
    received_time: { type: Date, default: Date.now },
    department_id: String
});

module.exports = mongoose.model('RL', RLSchema);

And I am creating a dynamic search with this since I dont know what they are going to search with. All I know is if you are searching based on received_time you need to send in the To and From:

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var regexp = require('node-regexp');

var RL = require('./app/models/rl');

var uristring = process.env.MONGODB_URI || 'mongodb://localhost/mydev';

mongoose.connect(uristring, function (error) {
    if (error) {
        console.log(error);
    }
});

app.get('/api/rl', function(req, res) {
    var findQuery = "{";
    var qry = "";

    if (req.query.agency_id) {
        findQuery = findQuery + " agency_id: \"" + req.query.agency_id + "\",";
    }

    if (req.query.department_id) {
        findQuery = findQuery + " \"department_id\": \"" + req.query.department_id + "\",";
    }

    if (req.query.user_id) {
        findQuery = findQuery + " \"user_id\": \"" + req.query.user_id + "\",";
    }

    var isOne = ((req.query.from) || (req.query.to));
    var isBoth = ((req.query.from) && (req.query.to));

    if (isOne) {
        if (isBoth) {
            findQuery = findQuery + " \"received_time\": { \"$lte\": " + req.query.to + ", \"$gte\": " + req.query.from + "},"
        } else {
            res.status(400).json("{ message: 'Missing the to or from time for searching}'");
            return res;
        }
    }

    qry = findQuery.substring(0, findQuery.length - 1);
    qry = qry + "}";
    if (qry.length < 2) {
        qry = "{}";
    }

    if (!isBoth) {
        qry = "";
    }

    RL.find(JSON.parse(qry)).toArray(function(err, doc) {
        if (err) {
            handleError(res, err.message, "Failed to get information");
        } else {
            res.status(200).json(doc);
        }
    });
});

Everytime I call this I get back: Error Internal Server Error

even if I remove all the code and just send in what is below I still get the Internal Server Error. Do you know why this would not work?

ResponderLocation.Find({ agency_id: req.query.agency_id }).toArray(function(err, rl){
        if(err)
            res.send(err);

        res.json(rl);
    });
4
  • 1
    1. Don't build json string and then parse it to object, just build the object. 2. Find should be lowercased to find. 3. You might want to console.log(err) to read the error. Commented Apr 22, 2017 at 7:26
  • thanks for the comment. Here is what I am seeing now: 1. Not sure how the object should look. When I tried it I got that the object could not be read in the console log. 2. Fixed the find to lowercase in the simple search still did not work. Console Log now said that we can not use toArray so I removed that and change it to this and it worked (sent me everything):ResponderLocation.find(function(err, rl){ So I guess I am down to how to dynamically creating the query Commented Apr 22, 2017 at 14:47
  • 1
    var query = {key1: 'value1', key2: 'value2', ...}; then if(condition){query[key] = something} finally, ResponderLocation.find(query).... Commented Apr 22, 2017 at 15:12
  • Normally, when you get a 500 error, you should be shown an error in your logs. I know for one thing .find().toArray() does not work. Commented Apr 22, 2017 at 15:42

1 Answer 1

1

As q4w56 pointed out, you should build an object opposed to a string and there is no function Find.

Here's how I would refactor your code:

app.get('/api/rl', function(req, res) {
    var query = {};
    if (req.query.agency_id) {
        query.agency_id = req.query.agency_id;
    }
    if (req.query.department_id) {
        query.department_id = req.query.department_id;
    }
    if (req.query.user_id) {
        query.user_id = req.query.user_id;
    }
    if (!req.query.from && !req.query.to) {
        // .json() expects a JSON not a string as argument
        return res.status(400).json({ message: 'Missing the to or from time for searching' });
    }
    query.received_time = {};
    if (req.query.from) {
        query.received_time.$gte = req.query.from;
    }
    if (req.query.to) {
        query.received_time.$lte = req.query.to;
    }
    // no need for toArray()
    ResponderLocation.find(query, function(err, locations) {
        if (err) {
            handleError(res, err.message, "Failed to get information");
        } else {
            // no need to send 200 status as that is default
            res.json(locations); 
        }
    });
});
Sign up to request clarification or add additional context in comments.

3 Comments

I am going to try your refactoring. I just now got it working using strings like because I was missing the \" in front of agency_id and after it. The JSON parser could not read agency_id as a string and was throwing an error.
Yep that worked except for the to and from. Thanks again for your help.
Double-check the format of req.query.from and req.query.to and the Date format that is saved in the collection. I think req.query.from and req.query.to need to be converted into Date objects as shown in this answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.