How to make an API call using meteor - javascript

Ok here is the twitter API,
http://search.twitter.com/search.atom?q=perkytweets
Can any one give me any hint about how to go about calling this API or link using Meteor
Update::
Here is the code that i tried but its not showing any response
if (Meteor.isClient) {
Template.hello.greeting = function () {
return "Welcome to HelloWorld";
};
Template.hello.events({
'click input' : function () {
checkTwitter();
}
});
Meteor.methods({checkTwitter: function () {
this.unblock();
var result = Meteor.http.call("GET", "http://search.twitter.com/search.atom?q=perkytweets");
alert(result.statusCode);
}});
}
if (Meteor.isServer) {
Meteor.startup(function () {
});
}

You are defining your checkTwitter Meteor.method inside a client-scoped block. Because you cannot call cross domain from the client (unless using jsonp), you have to put this block in a Meteor.isServer block.
As an aside, per the documentation, the client side Meteor.method of your checkTwitter function is merely a stub of a server-side method. You'll want to check out the docs for a full explanation of how server-side and client-side Meteor.methods work together.
Here is a working example of the http call:
if (Meteor.isServer) {
Meteor.methods({
checkTwitter: function () {
this.unblock();
return Meteor.http.call("GET", "http://search.twitter.com/search.json?q=perkytweets");
}
});
}
//invoke the server method
if (Meteor.isClient) {
Meteor.call("checkTwitter", function(error, results) {
console.log(results.content); //results.data should be a JSON object
});
}

This might seem rudimentary - but the HTTP package does not come by default in your Meteor project and requires that you install it a la carte.
On the command line either:
Just Meteor: meteor add http
Meteorite: mrt add http
Meteor HTTP Docs

Meteor.http.get on the client is async, so you will need to provide a callback function :
Meteor.http.call("GET",url,function(error,result){
console.log(result.statusCode);
});

Use Meteor.http.get. Per the docs:
Meteor.http.get(url, [options], [asyncCallback]) Anywhere
Send an HTTP GET request. Equivalent to Meteor.http.call("GET", ...).
The docs actually include some examples of using Twitter, so you should be able to get started with them.

on server side if you provide the call back to http.get it will be asynch call so my solutions to that undefined return on client was
var result = HTTP.get(iurl);
return result.data.response;
as i did not pass a call back to HTTP.get so it waited until i got response. hope it helps

Related

Hide an API key (in an environment variable perhaps?) when using Angular

I'm running a small Angular application with a Node/Express backend.
In one of my Angular factories (i.e. on the client side) I make a $http request to Github to return user info. However, a Github-generated key (which is meant to be kept secret) is required to do this.
I know I can't use process.env.XYZ on the client side. I'm wondering how I could keep this api key a secret? Do I have to make the request on the back end instead? If so, how do I transfer the returned Github data to the front end?
Sorry if this seems simplistic but I am a relative novice, so any clear responses with code examples would be much appreciated. Thank you
Unfortunately you have to proxy the request on your backend to keep the key secret. (I am assuming that you need some user data that is unavailable via an unauthenticated request like https://api.github.com/users/rsp?callback=foo because otherwise you wouldn't need to use API keys in the first place - but you didn't say specifically what you need to do so it is just my guess).
What you can do is something like this: In your backend you can add a new route for your frontend just for getting the info. It can do whatever you need - using or not any secret API keys, verify the request, process the response before returning to your client etc.
Example:
var app = require('express')();
app.get('/github-user/:user', function (req, res) {
getUser(req.params.user, function (err, data) {
if (err) res.json({error: "Some error"});
else res.json(data);
});
});
function getUser(user, callback) {
// a stub function that should do something more
if (!user) callback("Error");
else callback(null, {user:user, name:"The user "+user});
}
app.listen(3000, function () {
console.log('Listening on port 3000');
});
In this example you can get the user info at:
http://localhost:3000/github-user/abc
The function getUser should make an actual request to GitHub and before you call it you can change if that is really your frontend that is making the request e.g. by cheching the "Referer" header or other things, validate the input etc.
Now, if you only need a public info then you may be able to use a public JSON-P API like this - an example using jQuery to make things simple:
var user = prompt("User name:");
var req = $.getJSON('https://api.github.com/users/'+user);
req.then(function (data) {
console.log(data);
});
See DEMO

node.js and hapi: fetching data from a database synchronously

Coming from a .net world where synchronicity is a given I can query my data from a back end source such as a database, lucene, or even another API, I'm having a trouble finding a good sample of this for node.js where async is the norm.
The issue I'm having is that a client is making an API call to my hapi server, and from there I need to take in the parameters and form an Elasticsearch query to call, using the request library, and then wait for the instance to return before populating my view and sending it back to the client, problem being is that the request library uses a callback once the data is returned, and the empty view has long been returned to the client by then.
Attempting to place the return within the call back doesn't work since the EOF for the javascript was already hit and null returned in it's place, what is the best way to retrieve data within a service call?
EX:
var request = require('request');
var options = {
url: 'localhost:9200',
path: {params},
body: {
{params}
}
}
request.get(options, function(error, response){
// do data manipulation and set view data
}
// generate the view and return the view to be sent back to client
Wrap request call in your hapi handler by nesting callbacks so that the async tasks execute in the correct logic order. Pseudo hapi handler code is as following
function (request, reply) {
Elasticsearch.query((err, results) => {
if (err) {
return reply('Error occurred getting info from Elasticsearch')
}
//data is available for view
});
}
As I said earlier in your last question, use hapi's pre handlers to help you do async tasks before replying to your client. See docs here for more info. Also use wreck instead of request it is more robust and simpler to use

Which IP does a method use (user or server) on an API request?

I want to use an API in my meteor app. The API is restricted to a few requests per second per unique IP.
Does anyone know if the server IP or the user IP is used, when I make an API call in Meteor.methods like this
Meteor.methods({
searchTerm: function (term, lang) {
var parameters = {
"api_key": Meteor.settings.API
};
try {
var result = HTTP.call("GET", apiLink, { params: parameters });
return result.data;
} catch (e) {
return e;
}
}
}
Thanks in advance.
As already noted in the comments, if this code (the methods call itself) is runs on the server, then the method call (later with Meteor.call) is like a remote procedure call and the HTTP will be executed on the server only. If, however, this code, the methods call, is invoked on both the client and the server, then that defines a stub (http://docs.meteor.com/#/full/methods_header). That stub is executed in parallel on the client and the server. It is meant to help with latency compensation. I don't think you want that in this case though, since you are more concerned with the number of API requests. So I would suggest to leave it where it is right now (in the server folder somewhere). That way you can be sure that it will only execute on the server and not the client, and hence use the server IP.

Meteor - transfer data from API to Server to Client

I am struggling a bit with Meteor, i have this app that i would like to connect with an API client, which provides me a Secret API key, which i must not publish (in the client).
The thing is when i send the request, i get a JSON data, and i would like to pass this data to the client.
API > Server Call -> Client (Rendering).
But so far i have not come to a solution how can i do this.
I have a basic understanding how Meteor Works, but i have a good knowledge about JavaScript/NodeJS etc.
A little bit of help would really be appreciated.
Thank you.
This sounds like a good use case for a client making a call to a server-side method. The server can then use the secret key to make an HTTP request and send the result back to the client without exposing the key. Please note that your server-method must exist inside of a server directory to avoid inadvertently shipping the key to the client (see Structuring your application).
client
Meteor.call('getApiResult', function(err, result) {
if (result) {
return console.log(result);
}
});
server
Meteor.methods({
getApiResult: function() {
var secret = 'abc123';
try {
var result = HTTP.get('http://example.com/', {params: {key: secret}});
return result.data;
} catch (_error) {
return false;
}
}
});

Passing Function from Server to Client

for a recent project of mine I need to pass two functions from my server (written in node.js) to a client javascript tag. Actually to be completly correct, the client side javascript calls an XML request and I want to return some data and two functions for him which he should be able to use.
Second thing is I want to store a javascript function into a database in the server and then fetch it if the client requests it.
Anyone knows how this can be archieved and has some experience with it?
Note: you should really consider doing this in an HTTPS connection.
OK, so you want to receive code from the server and run it on the client. You could inject a script tag to the body and let the browser execute it. However, since you trust the code. I would simply use an eval call since that's what you'll doing anyway.
Here's how it would look in an Express app:
// server
function hello() {
alert('hello');
}
app.get('/get/js/code', function (req, res) {
res.send({
code: hello.toString(),
start: 'hello()'
});
});
// client (with jQuery)
$(function () {
$.getJSON('/get/js/code', function (json) {
eval(json.code + ';' + json.start + ';');
});
});

Categories