Push data from server to the client directly


#1

Hi,
I’am new to Meteor and I want to fetch data from the url (for e.g. youtube subscribers or whatever) on the server and push it to the client directly without saving in database. Is it possible to do with Meteor out of the box or should I use some additional libs? If yes, could somebody provide a little example for client and server scripts, please?
I’ve already checked these posts:
How to get the server data…
Best Way to handle a 3rd Party endpoint
But they hardly helped me.
Thanks!


#2

In principle, yes. If you give an example of the http call you want to use, I’m sure we’ll be able to help.


#3

It shoud retrieve just a JSON string. Also it is insensitive piece of data which is not necessary to store in database.

At the moment my code is looking like this:
client/main.js

import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';

import './main.html';

Template.body.onCreated(function() {
  this.someData = new ReactiveVar('');
  let someData = this.someData;
  Meteor.call("retrieveData", function(error, res) {
    console.log(res);
    someData.set(res);
  });
});

Template.body.helpers({
  someData() {
    return Template.instance().someData.get();
  }
});

server/main.js

import { Meteor } from 'meteor/meteor';

Meteor.startup(() => {
  // code to run on server at startup
});

let someData = '';

const https = require('https');

https.get('https://www.googleapis.com/youtube/v3/channels?part=statistics&id=channel_id&key=your_key', (resp) => {
  let data = '';

  // The whole response has been received.
  resp.on('end', () => {
    someData = JSON.parse(data);
  });

}).on("error", (err) => {
  console.log("Error: " + err.message);
});

Meteor.methods({
    retrieveData: function () {
        return someData;
    }
});

I’ve already found out how to call method on client to get some data from server, but how to subscribe on server’s method so that server will be pushing the data during some loop or data processing or whatever?


#4

Another more illustrative example:

server/main.js

import { Meteor } from 'meteor/meteor';

Meteor.startup(() => {
  // code to run on server at startup
});

let someData = 0;

setInterval(function() {
    someData += 1;
    pushToClient(someData);
}, 5000);

How to implement something like “pushToClient” method with Meteor?


#5

OK, firstly you can simplify your method using Meteor’s HTTP package:

import { Meteor } from 'meteor/meteor';
import { HTTP } from 'meteor/http';

Meteor.methods({
  retrieveData() {
    try {
      const someData = HTTP.get('https://www.googleapis.com/youtube/v3/channels?part=statistics&id=channel_id&key=your_key');
      return someData;
    } catch (err) {
      console.log();
      throw new Meteor.Error('oops', `Error: ${err.message}`);
    }
  }
});

However, to do what you want with a live data feed, you need to make use of the pub/sup API. I’ve put a sample snippet here:

import { Meteor } from 'meteor/meteor';

Meteor.publish('liveCounter', function () {
  let someData = 0;
  this.added('someClientCollection', 'counter', { someData });
  this.ready();
  setInterval(() => {
    someData += 1;
    this.changed('someClientCollection', 'counter', { someData });
    this.ready();
  }, 5000);
});

Then, on the client, you subscribe to the liveCounter publication and define a local, client-only collection called someClientCollection, into which the counts will be synchronised (the _id will be counter). The document will look like { _id: 'counter', someData: x }, where x will count 0, 1, 2 … over time.


#6

Thanks! It comes in handy for the first time, but seems that I should to develop a custom method for this purpose, also it will be more efficient to pass data right to the client api instead involving DB methods.


#7

There’s no actual DB involved in that example (no server-side, on-disk DB). It’s all websockets and minimongo access for the data.


#8

Oh, sorry, I see now. Thank you!


#9

Still in trouble with Meteor api, can’t get how to properly fetch a collection.

server/main.js

import { Meteor } from 'meteor/meteor';

Meteor.startup(() => {
  // code to run on server at startup
});

Meteor.publish('liveCounter', function () {
  let someData = 0;
  this.added('someClientCollection', 'counter', { someData });
  this.ready();
  setInterval(() => {
    someData += 1;
    this.changed('someClientCollection', 'counter', { someData });
    this.ready();
  }, 5000);
});

client/main.js

import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';

import './main.html';

const counter = new Mongo.Collection('someClientCollection');

Tracker.autorun(() => {
    Meteor.subscribe('liveCounter');
});

console.log(counter.find({}));

That doesn’t work :expressionless:


#10

Due to the lack of examples and api documentation now I have to look at firebase or express with websockets. Nice try, Meteor.
Meteor.unsubscribing('newUser');


#11

Have you read the Meteor Guide?

Also, I’d have been quite happy to have continued helping you. However, like everyone here, I’m not working 24x7 and have a day job.

So, yes, your client code is not going to work.


#12

Have you read the Meteor Guide?

Yes, I’ve already have read this. If there was a similar example, then I would not write here about it.

Also, I’d have been quite happy to have continued helping you.

Thanks.

So, yes, your client code is not going to work.

Thanks.


So, it was very easy to fix:

server/main.js

import { Meteor } from 'meteor/meteor';

Meteor.startup(() => {
  // code to run on server at startup
});

Meteor.publish('liveCounter', function () {
  let newData = 0;
  this.added('counterCollection', 'counter', { newData });
  this.ready();
  setInterval(() => {
    newData += 1;
    this.changed('counterCollection', 'counter', { newData });
    this.ready();
  }, 5000);
});

client/main.js

import { Template } from 'meteor/templating';
import './main.html';

var Counter = new Meteor.Collection("counterCollection");

Tracker.autorun(() => {
  Meteor.subscribe("liveCounter");
  console.log( Counter.findOne('counter') );
});

Seems it was a hard question for you.


All in all, Meteor is lack docs and examples, also overwhelming for new users and poorly supported by the community which always redirects to the documentation even in case of simple questions. This is the main problem of Meteor.


#13

Thank you so much for valuing my help.