How to view collection contents using Console.log

Hello all,

I have a very simple query. I am working on getting up publish / subscribe up and running as part of my learining, and am stuck with it at the moment.

I have a new meteor app created, no amends made. I also have a new db collection called dummy. All it contains is one record.

meteor:PRIMARY> db.dummy.insert({"text" : "this is a test message"})

Server/main.js contains the below:

import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';

ServerDummy = new Mongo.Collection('dummy');
console.log("Server log follows...")
console.log(ServerDummy.find({}));

Client/main.js contains the below:

import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import { Mongo } from 'meteor/mongo';
import './main.html';

ClientDummy = new Mongo.Collection('dummy');
console.log(ClientDummy.find({"text" : "Another dummy line"}));

When I save it, Iā€™m able to view the server side logs in the terminal. However, When I tried to view the client side logs in the browser, I only see ā€˜undefinedā€™. How exactly do I view the contents?

Secondly,

When I insert into the collection from server.js, the document looks completely different from the one I inserted directly in mongo shell. Could someone please explain what is going on?

server/main.js

ServerDummy.insert({"text" : "Another dummy record"});

My console looks like this:

=> Meteor server restarted
I20160526-14:17:29.525(5.5)? Server log follows...
I20160526-14:17:29.531(5.5)?      db: 
I20160526-14:17:29.531(5.5)?       { domain: null,
I20160526-14:17:29.531(5.5)?         _events: {},
I20160526-14:17:29.531(5.5)?         _maxListeners: 10,
I20160526-14:17:29.531(5.5)?         databaseName: 'meteor',
I20160526-14:17:29.531(5.5)?         serverConfig: [Object],
I20160526-14:17:29.531(5.5)?         options: [Object],
I20160526-14:17:29.532(5.5)?         _applicationClosed: false,
I20160526-14:17:29.532(5.5)?         slaveOk: false,
I20160526-14:17:29.532(5.5)?         bufferMaxEntries: -1,
I20160526-14:17:29.532(5.5)?         native_parser: false,
I20160526-14:17:29.532(5.5)?         bsonLib: [Object],
I20160526-14:17:29.532(5.5)?         bson: [Object],
I20160526-14:17:29.532(5.5)?         bson_deserializer: [Object],
I20160526-14:17:29.532(5.5)?         bson_serializer: [Object],
I20160526-14:17:29.532(5.5)?         _state: 'connected',
I20160526-14:17:29.533(5.5)?         pkFactory: [Object],
I20160526-14:17:29.533(5.5)?         forceServerObjectId: false,
I20160526-14:17:29.533(5.5)?         safe: false,
I20160526-14:17:29.533(5.5)?         notReplied: {},
I20160526-14:17:29.533(5.5)?         isInitializing: true,
I20160526-14:17:29.533(5.5)?         openCalled: true,
I20160526-14:17:29.533(5.5)?         commands: [],
I20160526-14:17:29.533(5.5)?         logger: [Object],
I20160526-14:17:29.533(5.5)?         tag: 1464252449432,
I20160526-14:17:29.534(5.5)?         eventHandlers: [Object],
I20160526-14:17:29.534(5.5)?         serializeFunctions: false,
I20160526-14:17:29.534(5.5)?         raw: false,
I20160526-14:17:29.534(5.5)?         recordQueryStats: false,
I20160526-14:17:29.535(5.5)?         retryMiliSeconds: 1000,
I20160526-14:17:29.535(5.5)?         numberOfRetries: 60,
I20160526-14:17:29.535(5.5)?         readPreference: [Object] },
I20160526-14:17:29.535(5.5)?      _primary: '127.0.0.1:3001',
I20160526-14:17:29.535(5.5)?      _oplogHandle: 
I20160526-14:17:29.536(5.5)?       { _oplogUrl: 'mongodb://127.0.0.1:3001/local',
I20160526-14:17:29.536(5.5)?         _dbName: 'meteor',
I20160526-14:17:29.536(5.5)?         _oplogLastEntryConnection: [Object],
I20160526-14:17:29.536(5.5)?         _oplogTailConnection: [Object],
I20160526-14:17:29.536(5.5)?         _stopped: false,
I20160526-14:17:29.536(5.5)?         _tailHandle: [Object],
I20160526-14:17:29.536(5.5)?         _readyFuture: [Object],
I20160526-14:17:29.536(5.5)?         _crossbar: [Object],
I20160526-14:17:29.537(5.5)?         _baseOplogSelector: [Object],
I20160526-14:17:29.537(5.5)?         _catchingUpFutures: [],
I20160526-14:17:29.537(5.5)?         _lastProcessedTS: [Object],
I20160526-14:17:29.537(5.5)?         _onSkippedEntriesHook: [Object],
I20160526-14:17:29.537(5.5)?         _entryQueue: [Object],
I20160526-14:17:29.537(5.5)?         _workerActive: false },
I20160526-14:17:29.537(5.5)?      _docFetcher: { _mongoConnection: [Circular], _callbacksForCacheKey: {} } },
I20160526-14:17:29.537(5.5)?   _cursorDescription: 
I20160526-14:17:29.537(5.5)?    { collectionName: 'dummy',
I20160526-14:17:29.538(5.5)?      selector: { text: 'Another dummy line' },
I20160526-14:17:29.538(5.5)?      options: { transform: null } },
I20160526-14:17:29.538(5.5)?   _synchronousCursor: null }
I20160526-14:17:29.530(5.5)? { _mongo: 
I20160526-14:17:29.530(5.5)?    { _observeMultiplexers: {},
I20160526-14:17:29.530(5.5)?      _onFailoverHook: { nextCallbackId: 0, callbacks: {}, bindEnvironment: true },

instead of just

I20160526-14:16:38.153(5.5)? Server log follows...
I20160526-14:16:38.160(5.5)? { _id: { _str: '5746a9f289519bc6a55891e7' },
I20160526-14:16:38.161(5.5)?   text: 'this is a test message' }

Thanks

You are currently printing your cursor; try to use ServerDummy.find({}).fetch() instead.

Ah thanks! That fixed one thing. However, when I have multiple items in
the collection, find.fetch seems to show only the latest object? How
exactly do I view all objects?

ServerDummy.find({}).fetch() does return all matched items. And by matched we mean all documents in your collection that match the selector.

So by searching like: ClientDummy.find({"text" : "Another dummy line"}), you will receive all documents where the property text equals ā€œAnother dummy lineā€.

ā€œAll documentsā€ are being returned when searching with an empty selector {}

Why not use the mongol tools so that you can have some kind of GUI for this?

I could, if I know what they are. Right now, iā€™m diving to get the basics right.

@bharathkeshav12 Ok mate well we have this pretty kick ass tool here https://github.com/msavin/Mongol

Also a website here http://meteor.toys/

Enjoy!

I got this to work. Now Iā€™m stuck with pub/sub. Is this maing sense to you?

server/main.js

ServerDummy = new Mongo.Collection('dummy');
// server publish
Meteor.publish('ServerPublication', function publishFunction() {
  return ServerDummy.find();
});

My understanding from the above is:

  1. Create ServerDummy Collection in meteor that has everything that the mongo db collection named ā€˜dummyā€™ has
    2.Create a publication data set called ā€˜ServerPublicationā€™ which in turn returns a cursor to everything (iā€™ve not specified any filtering criteria for now)

client/main.js

ClientDummy = new Mongo.Collection('ServerPublication');
Meteor.subscribe('ServerPublication');
console.log(ClientDummy.find().fetch());

My understanding of the above is:

1.Create a client side (mini mongo?) collection called ClientDummy. This mirrors ServerPublication Dataset ā€¦ Iā€™m confused here. Why is this required?
2.Subscribe to the publication called ServerPublication
3.Log whatever is returned by find().fetch() from the publication

How far is my understandign correct? Iā€™m making some mistake since the browser console rerutns [] and nothing else.

@bharathkeshav12 the client collection name should be equal to your server collection name. To answer your question #1, the client collection is used as cache. If you have multiple templates using the same data, this data wonā€™t be fetched twice from the server. The second template would get it from your local cache instead. So things are much faster. (This system is actually far more intelligent than I now describe, but lets keep it simple).

So correct would be:

// server
ServerDummy = new Mongo.Collection('dummy');

Meteor.publish('ServerPublication', function publishFunction() {
  return ServerDummy.find();
});

// client
ClientDummy = new Mongo.Collection('dummy');
Meteor.subscribe('ServerPublication');

Tracker.autorun(() => {
  console.log(ClientDummy.find().fetch());
});

Why the Tracker.autorun? Because the data might not yet been streamed from server to client upon your find request. Tracker.autorun forces this operation to rerun whenever the response data changes or when the subscription becomes ready.

Thereā€™s also my GoogleChrome extension: MiniMongoExplorer - itā€™s an easy way to explore all your client data.

2 Likes

Thank you so much @smeijer. This worked. Iā€™ll post back should I have further queries!

Follow up Question.

Iā€™ve setup the publish / subscribe as you had described.
Now, I have a simple body which should ideally throw out the ā€œtextā€ field from the database document.

testinghtml.html

<template name ='testinghtml'>
    <div id="page-wrapper">
        <ul> {{#each randomfunction}}
            <li>
                {{text}}
            </li>
        {{/each}}
        </ul>
    </div>                        
</template>      

client/main.html

<body>
{{> testinghtml}}
 </body>

client/main.js

ClientDummy = new Mongo.Collection('dummy');
Meteor.subscribe('ServerPublication');

Template.table.helpers({
    randomfunction() {
        recordObj = ClientDummy.find({"text" : " this is a test message"}); **// this returns all records from the db, correct? So recordObj ideally contains an array of records?**
        record = recordObj.text; **// how do I extract only the "text" field? **
        //alert (record)    ; **//this is just for my testing, ignore.**
}
});

Nothing really displays.

Update: The alert box in this fetches the right dataā€¦

Template.table.helpers({
    randomfunction() {
        recordObj = ClientDummy.findOne({"text" : "this is a test message"});
        record = recordObj["text"];
        alert (record)    ;
}
});

Again you seem to have some difficulties with the cursor.

I forget all best practices here; just trying to fix your code.

ClientDummy = new Mongo.Collection('dummy');
Meteor.subscribe('ServerPublication');

Template.testinghtml.helpers({
  randomfunction() {
    // return cursor
    return ClientDummy.find({"text" : " this is a test message"});
  }
});
<template name="testinghtml">
  <div id="page-wrapper">
    <ul>
      {{#each randomfunction}}
        <li>
          {{text}}
        </li>
      {{/each}}
    </ul>
  </div>                        
</template>

Your second snippet works; because you use findOne there instead of find. findOne returns an object, where find returns an cursor.

Thanks for this very useful