Vitalii Del Vorobioff
Vitalii Del Vorobioff

Reputation: 525

How to insert object into meteor collection

I am just starting to learn Meteorjs and have more questions than answers.

I want to store translations for my app into a temporary Collection, and subscribe Iron Router to its publishing. I have a dictionary-object that I want to insert into the Collection.

Here is the way I do it:

In server/translations.js

translations = {
  ru_RU: {
    'value1': 'translation1',
    'value2': 'translation2'
  },

  en_US: {
    'value1': 'translation1',
    'value2': 'translation2'
  }
};

In collections/translates.js

Translates = new Meteor.Collection('translations');
Translates.insert(translations);

In server/publications.js

Meteor.publish('translations', function (lang) { //<-- how to pass arguments?
    return Translations.find({'translations': lang});
});

In router.js

//use iron-router
Router.configure({
    layoutTemplate: 'main',
    notFoundTemplate: 'not-found',
    waitOn: function () { //waiting while data received and starting router job
        return Meteor.subscribe('translations');//<-- how can i use this data?
    }
});

How can I use these Objects client-side?

Upvotes: 3

Views: 8744

Answers (2)

hharnisc
hharnisc

Reputation: 927

There's a few client/server placement issues it seems like you're working through here too, but let's focus on your question and narrow down the problem.

Define Your Collection

Translations = new Meteor.Collection('translations');

Bootstrap DB Data

if (Meteor.isServer) {
    if (Translations.find({}).count() === 0) {
        Translations.insert({
            'translation' : 'ru_RU',
            'value1': 'translation1',
            'value2': 'translation2'
        });
        Translations.insert({
            'translation': 'en_US',
            'value1': 'translation1',
            'value2': 'translation2'
        });
    }
}

Publish

If you publish a collection with an argument

Meteor.publish('translations', function (lang) { //lang argument
    return Translations.find({'translation': lang});
});

Subscribe

You can subscribe with the argument like this

Meteor.subscribe('translations', 'ru_RU'); // pass in the other language code

For the sake of simplicity I'll leave out iron-router, since there's a few things you have to do to setup ({{yield}} in your main template and the Router.map -- Iron Router Quickstart)

Template Helper

Template.myTemplate.helpers({
    translations: function() {
        // return all subscribed translations
        return Translations.findOne({});
    }
});

Template

<template name='myTemplate'>
    {{translations.value1}}<br>
    {{translations.value2}}
</template>

Upvotes: 4

musically_ut
musically_ut

Reputation: 34288

There are two core points to understand here:

  1. The Translates collection exists on the Client as well.
  2. Subscribing to a source makes all the documents published by it available on the client: irrespective of which collection they belong to. You can even return an array of cursors to publish from more than one collection.

Apart from that, there are a few issues with the you queries and data model.

With your definition of translations variable, the query Translations.find({'translations': lang}); is not going to find anything since it will try to look for documents where a field translation equals the passed object. That is probably not what you want.

I would suggest making your translation variable hold the following data:

translations = [
  {
    'translation' : 'ru_RU',
    'value1': 'translation1',
    'value2': 'translation2'
  },
  {
    'translation': 'en_US',
    'value1': 'translation1',
    'value2': 'translation2'
  }
];

Then your query is likely to return what you want.

Another suggestion is that Translates.insert(translations); is going to enter an object into the table each time the server runs. That is also probably not what you want (perhaps you are not doing that on the actual client). The way to address it is by checking whether the collection is empty at the start:

if (Translation.find({}).count() === 0) Translation.insert(translations);

Finally, while subscribing, you can pass in the variables to the subscribe function:

waitOn: function () {
    return Meteor.subscribe('translations', 
                              /* user preference here */
                             this.params.userLanguagePreference
                           );
}

Finally, to access the collection on the client, just use Translation.find({}) and you will get a cursor which will iterate over all the documents which have been published for your subscriptions for the client.

Upvotes: 0

Related Questions