0

In LiveCode I have a stack connecting to a localhost MongoDB, the stack has a button with a mouseup handler and the function JSONToArray from MergJSON and two fields: "A" to receive the server answer "as is" and field B" to receive the decoded JSON.

This is the script of the button:

on mouseup
  set the hideConsoleWindows to true
  put shell("C:\\mongodb\bin\mongo.exe --eval" && quote & \ 
    "printjson(db.test.findOne())" & quote) into pJSON
  put pJSON into fld "a"
  put JSONToArray(pJSON) into tArray
  put tArray["a"] into fld "B"
end mouseup

The contents of fld "A" after mouseup is:

MongoDB shell version: 2.2.7
connecting to: test
{ "_id" : ObjectId("52e3f87c8da8b1efb07004c9"), "a" : 1 }

The script fails with the following LiveCode error:

        executing at 8:58:32 PM
Type    could not decode JSON: invalid token near 'MongoDB'
Object  Completo
Line    repeat for each line tKey in mergJSONDecode(pJSON,"tArray")
Hint    could not decode JSON: invalid token near 'MongoDB'

If I change the script to:

on mouseup
  put shell("C:\\mongodb\bin\mongo.exe --eval" && quote & "printjson(db.test.find())" & quote) into pJSON
  put pJSON into fld "A"
end mouseup

Field "A" gets this:

MongoDB shell version: 2.2.7
connecting to: test
{
    _"_mongo" : connection to 127.0.0.1,
    _"_db" : test,
    _"_collection" : test.test
    _"_ns" : "test.test",
    _"_query" : {
    __
_},
    _"_fields" : null,
    _"_limit" : 0,
    _"_skip" : 0,
    _"_batchSize" : 0,
    _"_options" : 0,
    _"_cursor" : null,
    _"_numReturned" : 0,
    _"_special" : false,
    _"help" : function () {
    print("find() modifiers");
    ...
    ...
    ...
}

I am shortening the actual field "A" content, it has a lot of text.

Can you guide me please? What I am doing wrong? Why I am not getting a JSON. I checked { "_id" : ObjectId("52e3f87c8da8b1efb07004c9"), "a" : 1 } using an online service finding that it is not a valid JSON.

Mark
  • 2,380
  • 11
  • 29
  • 49
Javier
  • 75
  • 5

2 Answers2

0

Try feeding only the string from { until } without the preceding lines.

on mouseUp
  set the hideConsoleWindows to true
  put shell("C:\mongodb\bin\mongo.exe --eval" && \
    quote & "printjson(db.test.findOne())" & quote) into pJSON
  put pJSON into fld "a"
  put JSONToArray(line 3 to -1 of pJSON) into tArray // <-- this line changed
  put tArray["a"] into fld "B"
end mouseUp
Mark
  • 2,380
  • 11
  • 29
  • 49
  • Yes `.findOne()` would return only one record as something that can be interpreted to JSON, but I cannot say tou are understanding the problem. The point is that `.find()` does not return something that can be serialized as JSON. You seem to have missed the point while focusing on the `livecode` component. (Additionally keep in mind this question looked a lot different many hours ago, but the point is still valid) – Neil Lunn Feb 25 '14 at 16:15
  • We should probably wait for Javier to comment on our answers. – Mark Feb 25 '14 at 21:57
  • 1
    Neil, Mark, thank you very much. I'll try to change the script to: put JSONToArray(line 3 to -1 of pJSON) into tArray , as Mark suggest, Neil, I'll re-read the info.mation about .find to be sure I allways get a JSON. Please wait for my next post. – Javier Feb 27 '14 at 15:47
  • Javier, when you have new results, you can update your question to include those. – Mark Feb 27 '14 at 17:53
  • @Mark , Neil Lunn pointed out correctly that I was getting was a cursor not a JSON, his explanation of the way the shell works regarding find() was accurate, I tried db.test.find() and the results are identical when issuing: var c = db.test.find() ; while ( c.hasNext() ) printjson( c.next()). The thing now is how to code this in LC, I tried: put shell("C:\mongodb\bin\mongo.exe --eval var c = db.test.find() ; while ( c.hasNext() ) printjson( c.next() )") into pJSON put pJSON into fld "A" but field "A" gets error MongoDB... connecting to: c SyntaxError: missing variable name (shell eval):1 – Javier Mar 02 '14 at 05:25
-3

TO answer the question "What am I doing wrong?" you first need to understand what you are doing when you invoke .find() on a collection.

Now as the documentation in that link will tell you (right at the top of the page) you are not returning results from this call but in fact you are returning a cursor. Now what you may see when invoking this is the shell is a series of documents come out.

But the only reason this happens is that the shell (in interactive form) acts as a REPL and evaluates your statements in order to print the output. So the interactive shell is evaluating your cursor and calling a .next() method on that several times. This is only a convenience function while working in the shell.

In order to get the results programmatically as you intend to do, you need to do something with this cursor to actually see the results. Now you could create a loop where you iterate over the results calling .next() each time, but for your purposes the .toArray() method should suffice.

So in a slightly expanded way, for clear definition you would have a script form like this:

var cursor = db.test.find();

var results = cursor.toArray();

printjson( results );

Or as the general one liner using method chaining:

printjson( db.test.find().toArray() )

And that will emit the JSON Array of documents you need.

Alternately you can use the .findOne() method which will just return a single document which you can pass in to the printjson() function.

Community
  • 1
  • 1
Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
  • I don't see how this solves the problem. OP doesn't need a result of type array. In LiveCode, everything is a string. The Json result has to be a correctly formatted string, that can be fed to the MergJson external. – Mark Feb 25 '14 at 12:04
  • @Mark there is a clear distinction in the answer. The OP is not returning anything that is valid as the result is a cursor and that I gave them the results (from the printjson() method) as a string. – Neil Lunn Feb 25 '14 at 16:11
  • HI, I change the line in the mouseuphandler to: put JSONToArray(line 3 to -1 of pJSON) into tArray // <-- this line changed. But I get the error: Type could not decode JSON: invalid token near 'Sat' Object Completo Line repeat for each line tKey in mergJSONDecode(pJSON,"tArray") Hint could not decode JSON: invalid token near 'Sat' pJSON still not a valid JSON, I think Neil pointed out that pJSON is a cursor. – Javier Mar 01 '14 at 14:11
  • So taking in consideration that what I am getting as result is s cursor, the problem is how to iterate on it using LC commands to build an array to be passed to the function. Please correct me if I am wrong. – Javier Mar 01 '14 at 14:21