Google Maps Javascript API on Node.JS - node.js

I'm working on a NodeJS project that requires me to obtain driving directions on the server.
It seems like an obvious choice to use the Google Javascript API Version 3. But it seems like it was made only to be used on HTML pages, and not on server-only scripts. Even loading the API requires a script-tag or document.write.
Then I turned to node-googlemaps which is based on the Google Maps API. Sadly, this also does not work for two reasons:
the returned travel steps do not contain the path field
the license does not allow to use that API without displaying a map to a user
What can I do? Are there any workarounds or other APIs I could use?
Best, Boris

Actually you can do it on the backend or frontend, and the approach is basically the same.
All you gotta do is a request to the endpoint passing the right parameters, then the API will return you everything you need.
So, roughly it would be something like this:
var http = require('http');
var options = {
host: 'maps.googleapis.com',
path: '/maps/api/directions/json?origin=Toronto&destination=Montreal&avoid=highways&mode=bicycling'
}
callback = function(response) {
// variable that will save the result
var result = '';
// every time you have a new piece of the result
response.on('data', function(chunk) {
result += chunk;
});
// when you get everything back
response.on('end', function() {
res.send(result);
});
}
http.request(options, callback).end();
And here's the documentation's link if you want to dig deeper on this: https://developers.google.com/maps/documentation/directions/?hl=nl
Cheers,

Related

With Node.js, how can I make two HTTP GET requests and combine the resulting data and send it back to a user?

Say I have the following code that sends back json data (that I get from example.com first) back to a user that made a post request
app.post('/riot', function(request, response) {
var riotAPI = https.get("https://example.com", function(riotResponse){
var body = "";
riotResponse.on('data', function(chunk){
body+= chunk;
});
riotResponse.on('end', function(){
response.type('json');
response.end(body);
});
});
});
What do I do if I want to get more data from a different website and send json data from both website back to user? I am using express.
There are a number of ways you can do this. I would suggest using the request npm module instead of calling https directly. With request you can simply pass in callback which is called when a request finishes, so no need to deal with chunks of data.
If you take this approach then you can just use something like async.parallel() to run both requests in parallel. async.parallel takes one callback that is called when all of its async functions have finished.. and that is where you would send your response.

mean.js $resource to call express server RESTful API

I come from a completely non web-development background, but having seen the traction that mean.js is picking up, i really wanted to give it a shot.
I've followed tutorials online so I've basically started, run and modified the example app but am now trying to do something thats off of the tutorials. As a result I have a basic understanding of express and angular
I've been trying to integrate the activator npm package (https://www.npmjs.org/package/activator) into the app, and while I've managed to fit in the angular bits, I'm having trouble plugging in the express bits. Which brings me to a very fundamental doubt, the answers to which I haven't really been able to find. I know that in Mean, the angular code connects to the express code using REST API's created in express. And that I believe happens using angular services. But I don't understand how. For instance, the users module has the following service defined:
angular.module('users').factory('Users', ['$resource',
function($resource) {
return $resource('users', {}, {
update: {
method: 'PUT'
}
});
}
]);
Can anyone explain how this works ?
Also if I have some code on the express side say:
var sayHello = function(name){
return "Hello"+name;
}
How can I call this through angular? I know we use $resource for that from the ngResource module, but I dont really understand how.
Any help would be much appreciated.
Connecting these things together can be a bit confusing. I think the thing to understand is that when using Express on the server side, you need to model your API around a route, and handle communication with the req and res objects you'll be handed.
So first on the client side, taking a simple example, I generally use the $resource as a way of wrapping the HTTP/ajax details which I don't want to worry about. So I'll write my service as such:
"use strict";
angular.module("myModule").factory("UserService", ["$resource",
function($resource) {
var resource;
resource = $resource("/api/users", null, {
listUsers: {
method: "GET",
isArray: true
}
});
return resource;
}
]);
(Notice that I'm passing the isArray parameter to this resource since I expect an array of users to return -- which is not always the case with all APIs).
Then to take advantage of that resource, perhaps in my controller I'll have code like this:
"use strict";
angular.module("myModule").controller("UserCtrl", ["$scope", "UserService",
function($scope, userService) {
$scope.loadUsers = function() {
userService.listUsers(function(resource, headers) {
// this function is called on success, with the result
// stored within the `resource` variable
// ...
}, function(response) {
// this function is called on error
// ...
});
};
}
]);
Now assuming everything goes right on the server side, we'll receive our list of users to play around with passed in to the first function as the resource.
On the server side, we'll need to configure our routes (wherever those are configured) to include our users controller, which will serve as our users API. So perhaps within this app we have a routes directory which contains all our Express routes (see the app.route documentation for more information on Express routes). We also have a controllers directory which contains all our Express controllers that handle the logic for our routes. Keeping with the "users" example, we'll have a route defined that matches the /api/users $resource route we defined above in our Angular code:
"use strict";
var controller = require("../controllers/user");
module.exports = function(app) {
app.route("/api/users").get(controller.listUsers);
};
This code takes in the Express app as input, and defines a single route for /api/users as a GET HTTP request (notice the .get function called). The logic for this route is defined in the user controller, which would be something like this:
"use strict";
exports.listUsers = function(req, res) {
var users;
// ...somehow populate the users to return...
res.send(users);
};
We've left the details on how to populate that array of users, but hopefully this gives you the idea. This controller is passed the req (request) and res (response) HTTP objects as input, so it can query the request object for details on what the user passed in, and must send some response back to the user to complete the request/response loop. In this example I'm using the res.send function to simply send back our JavaScript array (which will be passed as JSON).
Does that make sense?

nodejs couchapp does not link css file

I have made a couchdb design document which works perfectly on the following url
http://localhost:5984/db/_design/app/index.html
Now the problem is i am trying to fetch the page contents and display it from node js but only the html page is displayed the linked css and js files are not working and when i tried to narrow down the problem i found that the css and js files are suppose to have the login credentials of the couchdb and is not linking I even tried adding the auth header in the response parameter but still no luck
var http = require('http');
var json;
var root = new Buffer("admin:pass").toString('base64');
http.createServer(function(req, res) {
res.setHeader('Authorization', root);
res.writeHead(200, { 'Content-Type':'text/html' });
couchPage();
res.end(json);
}).listen(8080);
function couchPage() {
var options = {
hostname: 'localhost',
port: 5984,
path: '/db/_design/app/index.html',
auth: 'admin:pass',
method: 'GET'
};
var req = http.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
json = chunk;
});
});
req.end();
}
could any one please guide me where am i wrong
I think this has nothing to do with couchdb authorization. The problem is that you do not perform any routing on your nodejs server. That is, the browser makes a request to localhost:8080 and receives the content of /db/_design/app/index.html as an answer. Now, the browser detects a link to a stylesheet, say "style.css". It performs a request to localhost:8080/style.css but your nodejs server simply ignores the "style.css" part of the request. Instead, the client will receive the content of /db/_design/app/index.html again!
If you want to serve attachments of your design document through nodejs, you have to parse the request first and then retrieve the corresponding document from couchdb. However, I don't think that you actually want to do this. Either you want to use couchdb in a traditional way behind nodejs (not directly accessible from the client) and then you would just use it as a database with your html (or template) files stored on disk. Or you want to directly expose couchdb to the client and make nodejs listen to events via the couchdb _changes feed.

Pass additional arguments to node.js callack

I have created a rest client to make calls outside of my application. I want to send the data I receive back from the rest calls to the client's web browser.
Something like the following, but what is the best way to structure the code to allow access to the response to write back to the web browser with as loose coupling as possible? I don't want to define the rest client within a request handler.
var servReq = http.request(options, function(restResponse){
var status = restResponse.statusCode
var headers = restResponse.headers
restResponse.setEncoding("utf8");
d='';
restResponse.on('data', function(chunk){
d += chunk;
})
restResponse.on('end', function(restResponse){
// res would be a response to write back to the client's web browser
// with the data received from the rest client.
res.writeHead(200, {"content-type":"text/plain"})
res.write(d)
res.end();
})
}
Using request, you can pipe the API response straight to your application's response. This way it'll be completely loosely coupled—your server will return precisely what the API returns.
request(options).pipe(res);
https://github.com/mikeal/request#streaming

Upload a photo to facebook album

I have a nodejs (+express + mongodb,gridstore) backend, and want to upload a photo to a facebook album.
I came across 2 methods. the first ( https://developers.facebook.com/blog/post/526/ ) needs to get the full url resource of my picture, which I don't have as it is data that I pull from gridstore,
and the second ( https://developers.facebook.com/docs/reference/api/album/ ) is very poorly documented, via the Graph API, where I can't figure out what my request should look like. (the form-data, what fields should it have, how to convert my data blob\stream from gridstore to it)
Here is what I currently have, and doesn't work:
facebook.uploadPhoto = function (token, albumId, photo, callback) {
var fb = fermata.json('https://graph.facebook.com/' + albumId);
fb.photos({access_token:token}).post({'Content-Type':"multipart/form-data"}, {source:{data:photo}}, callback);
};
Any help would be much appreciated
There is a good chance the file is not properly serialized. Fermata will take a node File buffer via data. Have you tried passing that instead?
fs.readFile("/path/to/photo.jpg", function (err, data) {
fermata.json("https://graph.facebook.com/graph/api").post({"Content-Type":"multipart/form-data"}, {fileField: {data:data, name:"", type:""} }, callback);
});
Adding your access token etc..
I solved this problem by using a simple POST to the facebook graph API using the poster module.
var options = {
uploadUrl: 'https://graph.facebook.com/'+user+'/photos?access_token='+accessToken,
method: 'POST',
fileId: 'source',
fields: {'message':''} // Additional fields according to graph API
};
var fileName = ''; // Local or remote url where to find the image
poster.post(fileName, options, function(err, data) {
if (err) {
//Something went wrong
} else {
// Everything ok
}
});
Honestly, I've got limited experience working with the Facebook graph API and mostly using PHP and Java.
Here is some streams that you might find helpful:
Upload Photo To Album with Facebook's Graph API
Facebook Graph API - upload photo using JavaScript
Basically, I recommend you punt a little in your implementation and code it in the following way:
Create a REST web service function call in Node.js to output a single image from gridstore using an internal UID.
Code your uploadToFacebook function to use an image URL that calls the REST web service function.
Basically, this would allow you to validate the image output by pointing your browser to the REST web service and avoid any blob\stream conversions inside your uploadToFacebook function. I'm assuming you store the image in gridstore vs. mongodb.
hope that helps...

Resources