0

I have a MongoDB aggregate framework that uses a startDate, endDate and intervalValue to query my database. However these variables are hardcoded. I would like to use a datepicker to send startDate, endDate and intervalValuefrom a webpage.

I initially thought I should split the JS file. One handling the request from the webpage and the other handling the GET function. Unfortunately I have reached a dead-end. I'm unable to use variables declared in sandbox.js in test.js.

Also I'm a bit confuse on how to structure my JS files to input the date and display the output.

sandbox.js

function myTime() {


    var startValue = document.getElementById("startTime").value;
    var endValue = document.getElementById("endTime").value;
    var intervalValue = document.getElementById("interval").value;
    var startDate = new Date("1/1/2015 " + startValue);
    var endDate = new Date("1/1/2015 " + endValue);
    var offset = intervalValue * 1000 * 60;
}

test.js

{ $match : { datetime : { $gt : startDate, $lt : endDate } } },
  {
   $group: {
    _id:{
    "$add": [
     { "$subtract": [
     { "$subtract": [ "$datetime", new Date(0) ] },
     { "$mod": [
    { "$subtract": ["$datetime" , new Date(0) ] },
    offset]}] },
    new Date(0)
     ]},
            Humidity: {$avg: "$humidity"},
            Temperature: {$avg: "$temperature"}

            },
            },

      { $project : { _id : 1 , Humidity : 1, Temperature: 1 } },
       // { $limit : 10 },
       { $sort :  {"_id":1, "Humidity":1, "Temperature": 1}}

I will be glad if I can get some help. Thanks

Community
  • 1
  • 1
Ekom
  • 419
  • 3
  • 7
  • 18

1 Answers1

1

Firstly, you need to make sure that both files are included in the HTML page that you are loading (i.e. your form).

Next, I see that your test.js file is simply a JSON object.

I would recommend changing this so that you return a JSON object via a function call rather. This will allow you to pass through your gathered inputs into the function to return your required JSON object to send to Mongo.

I would recommend giving the following changes a try:

sandbox.js changes

function myTime() {
     var result = {}
     result.startValue = document.getElementById("startTime").value;
     result.endValue = document.getElementById("endTime").value;
     result.intervalValue = document.getElementById("interval").value;
     result.startDate = new Date("1/1/2015 " + startValue);
     result.endDate = new Date("1/1/2015 " + endValue);
     result.offset = intervalValue * 1000 * 60;
     return result;
   }

This will allow you get get all the variables into a result to pass through to the test.js file

test.js changes

function getMongoObject(values) {
   return { "$match" : { "datetime" : { "$gt" : values.startDate, "$lt" : values.endDate } } },
        {
         "$group": {
        "_id":{
        "$add": [
         { "$subtract": [
         { "$subtract": [ "$datetime", new Date(0) ] },
         { "$mod": [
        { "$subtract": ["$datetime" , new Date(0) ] },
        values.offset]}] },
        new Date(0)
         ]},
        "Humidity": {$avg: "$humidity"},
        "Temperature": {$avg: "$temperature"}

        },
        },

       { "$project" : { "_id" : 1 , "Humidity" : 1, "Temperature": 1 } },
       // { "$limit" : 10 },
       { "$sort" :  {"_id":1, "Humidity":1, "Temperature": 1}}
}

Once you've made those changes to the test.js file, you can execute the following where you want to get the JSON object to pass to Mongo.

var mongoValues = getTime();
var mongoObject = getMongoObject(mongoValues);

Now you can use mongoObject to send to the DB.

UPDATE: Approach 2:

If you do not want to send the variables through to the test.js file you will need to make your variables in the sandbox.js file global. Currently they are "private" (scoped only to the function)

Try these changes to sandbox.js

var startValue, endValue, intervalValue, startDate, endDate, offset;
function myTime() {
     startValue = document.getElementById("startTime").value;
     endValue = document.getElementById("endTime").value;
     intervalValue = document.getElementById("interval").value;
     startDate = new Date("1/1/2015 " + startValue);
     endDate = new Date("1/1/2015 " + endValue);
     offset = intervalValue * 1000 * 60;
   }

In my opinion, option 1 is still better because it allows you to control what the variables are that you are binding to your JSON object that you will be passing to Mongo.

With this method, you could accidentally get different results in your JSON object due to the variables not being set at the time test.js is invoked or due to the variables being accidentally overridden.

UPDATE 3

In order to access the startDate and other variables in the test.js file you will need to make the JSON object a variable.

I have made a github repo for a test to show you want I mean, check it out here: https://github.com/NewteqDeveloper/so-q-41462690 From this example you will note that the alert displays 2. (startdate + 1).

For more information check this stackoverflow page: Can I access variables from another file?.

An important note to make is that you need to include the sandbox.js file before the test.js file in the html page.

Newteq Developer
  • 1,038
  • 14
  • 27
  • Thanks for your prompt response. My `test.js` sends a JSON response to another JS file that plots a chart of the values in the array. So basically I'm looking for a method to gets the variable from the webpage and when I submit it reloads my chart. – Ekom Jan 04 '17 at 12:03
  • If you do not want to pass the results of function `sandbox.js` into the `test.js` file you will need to make your variables that you are setting in the `getTime()` function to be global. By this, I will update the answer to reflect this option – Newteq Developer Jan 04 '17 at 13:19
  • The second option is what i was looking for. However I'm still getting `startDate is not defined` do I need to include or require anything from `sandbox.js` Thanks – Ekom Jan 04 '17 at 17:16
  • You might need to make your JSON object either a function or a variable that holds the JSON object, rather than just simply the JSON object. Please see my update in the answer. You'll note that on the github repo there is a **test2.js**, it will show you how to do it as a variable which you can use later (note that the value is logged to the console) – Newteq Developer Jan 05 '17 at 07:25
  • Thanks for getting back to me. Let me explicitly explain how my program works. I'm sending temperature and humidity from an Arduino to my MongoDB via Websocket. I'm looking to create a web application that displays the current data reading and also shows history events in a chart and table. I have chosen the MongoDB aggregate framework to filter my database. However I will like to bind a datepicker that sends `startDate` and `endDate` to my MongoDB framework and have these values displayed on my chart after I submit from the the form. – Ekom Jan 05 '17 at 07:41
  • OK, I see. @Ekom Have you tried my approach. I'm just not sure why would it not work if you simply created an object (in the Mongo format) via a method (i.e. the way I've done it in my github implementation for test.js)? So basically, have a method called on the website that invokes the method in test.js to return the mongo JSON aggregate. Once you've got that response, send that variable through the websocket. – Newteq Developer Jan 06 '17 at 15:09
  • I tried your approach and it worked out. Thanks a million. – Ekom Jan 06 '17 at 20:35
  • Super, glad to help :) – Newteq Developer Jan 08 '17 at 17:24