using api's in node.js - javascript

i'm running the server using node.js on localhost:8080 and i want to use api's in my HTML document. the html document is external, so how would i go about sending the api data to the web page. for example, i have a weather api in my javascript file:
var yw = require('weather-yahoo');
var ans = {};
function loadWeather() {
yw.getSimpleWeather('denver,co').then(function(res){
console.log(res);
ans=res;
alert(ans);
}); // pulls just some of the info from yahoo weather
}
and i've called it on button click in my html file like so:
<button onclick="loadWeather();">View article descriptions</button>
but it doesn't work. i also have the included the source of the javascript file in this document by the way.

You have a function on your node server, but now you'll need to expose it to your client. The simplest way to do this is using the express module.
If you are not completely familiar with node modules and express, there are plenty of startup tutorials available such as https://expressjs.com/en/starter/hello-world.html.
In your case you would need to create an API call that will call the weather data function.
var app = require('express')(),
yw = require('weather-yahoo');
function loadWeather() {
return yw.getSimpleWeather('denver,co');
}
app.get('/weather', function(req, res){
loadWeather().then(function(result){
return res.json(result);
},
function(error){
res.status(400).json(error);
});
});
app.get('/', function(req, res){
res.sendFile(process.cwd() + '/index.html', null, function(err) {
if(err){
res.sendStatus(404);
}
});
})
app.listen(3000, function () {
console.log('Listening on port 3000');
})
This is the simplest of API calls that can easily be extended to return weather for other regions by adding query parameters to the api call.
On the client side, you will now need a function to call your api.
As the example above serves the index file as it's main page, a simple JQuery get call to weather will return the data you want as it is on the same host.
<script>
//This call uses JQuery, make sure you have it referenced in your site
function callAPI() {
$.get("weather", function(data, status){
$('#result').val(JSON.stringify(data));
});
}
</script>
<button onclick="callAPI()">Get Weather</button>
<br>
<textarea id="result" style="width:500px; height:500px"></textarea>

Related

Routing in MEAN Stack - Routing help for Angular js and node.js using expressjs framework

I have solved the problem but I am still unsure if the way I am doing it is correct. If there is any alternative method via which I can send the file and data in one go then that would be more useful. Please give your inputs on the same.
I am using Angular js for the front end and Express js over node.js at the backend.
What I am trying to do?
I am trying to implement something like facebook's facility to provide you unique profile names or say user names.
Therefore - The user let's say types domain.com/hisprofileid
Now, what I want to do is a search should be done on the server side which would send response to front end with exact data depending upon the search's result.
and then front end will load the data.
What I have done till now?
Honestly speaking I haven't been able to think it out properly and the system I have put in place doesn't work.
This is what I have done. The root call that is localhost:portnumber on server side sends a file called index.html. This is just index file and nothing else.
Now on the server side I have made route to handle localhost:portnumber/anything which sends profilepage.html file as response.
Now the controller of that profilepage.html's controller using $locationprovider has this code to make a separate call to server side (Please refer to code below) [I strongly believe this is insignificant and that is why I'm lost]
Please look at some codes given below.
Front end part
$routeProvider
.when('/', {
templateUrl: 'index12.html',
controller: 'someCtrl'
})
.when('/:merchantid', {
templateUrl: 'index12.html',
controller:'userCtrl'
})
app.controller('userCtrl', function ($scope, Upload, $timeout, $http) {
console.log("Here");
var merchantid = "suresh";
$http.get('/merchant/' + merchantid ).success(function(response)
{
console.log("response");
console.log(response);
});
});
Server Side
app.get('/', function (req, res) {
console.log("Global");
res.sendFile(__dirname + '/public/index13.html');
});
app.get('/:merchantid', function (req, res) {
console.log("we are here");
console.log(req.params);
res.sendFile(__dirname + '/public/index12.html');
});
app.get('/merchant/:merchantid', function (req, res) {
console.log("Detail here");
console.log(req.params);
res.json({message: 'here'});
});
Please suggest something.
This is what I have done to solve the problem.
localhost:portnumber/anything - When this is called I am making a call to the server directly and a check is made if that particular person actually has signed up or not and then based on that result the appropriate page is opened.
app.get('/:profileid', route_profileid.fetchprofile);
Then the function to handle the data associated with it.
modename.findOne({
'profileid': uniqueid
}, function (err, docs) {
if (err) {
console.log("Error in finding data" + err);
} else {
if (docs) {
console.log(process.cwd());
res.sendFile(process.cwd() + '/public/profile.html');
}
if (!docs) {
console.log("Nothing Found related to that query");
res.sendFile(process.cwd() + '/public/error.html');
}
}
Now the profile page is loaded with profile data of that specific used and then here is the code of angular's router. [This angular code is attached to the profile page which will be shown.]
$rootScope.$on('$routeChangeSuccess', function () {
console.log($routeParams.profileid);
var profileid = $routeParams.profileid;
$http.get('/profile/' + profileid).success(function (response) {
console.log(response);
$scope.profile = response;
});
});
Note: Inclusion of $RouteParams, $route, $routeScope and ngRoute module to facilitate the activity is required.
Here a new request is made for the actual data of that user.
app.get('/profileid/:profileid', route_profiledata.profiledata);
and then in that specific function data is fetched from the db and appropriate response is sent back to the user.

How to get entire request in node.js

I would like to get the entire request (header and body just as they appear when they arrive at the application) in Node.js. I'm able to get it by reading directly from the socket on connection (example below), but I haven't found a way to associate it with a particular request object as it's processed by the server.
...
var server = http.createServer(app).listen();
server.on('connection', function(socket) {
socket.on('data', function(data) {
console.log(data.toString());
});
});
...
app.get("/", function(req, res) {
//get the data that would be output from the above snippet in this context
//do something with it
});
This is just one example to illustrate what I'm looking for, I'm open to any method to achieve this other than attempting to reconstruct the request from information provided in the request object.

any way to send a function with socket.io?

guys.
I want to send a function to browser with socket.io, but failed to do it.
On server side, I response a function with emit, but I get a undefined on browser.
Is there any way to get a function from server with socketio?
there is my code.
// server.js
var static = require('node-static');
var http = require('http');
var file = new(static.Server)();
var app = http.createServer(function(req, res) {
file.serve(req, res);
}).listen(8000);
io = require('socket.io').listen(app);
io.sockets.on('connection', function(socket) {
socket.on('schedule', function() {
console.log('SCHEDULE TASK');
socket.emit('schedule', function() { console.log('hello world'); });
});
});
// client.js
var socket = io.connect('http://localhost:8000');
socket.on('schedule', function(fn) {
fn();
});
socket.emit('schedule');
You cannot send an actual function. You could send a string of Javascript and then you could turn that into a function in the client.
But, I'd suggest you really ought to rethink what you're trying to do here. Generally, the client already has the code it needs (from the script tags that it downloaded) and you send the client data which it then passes to the code it already has or data that it uses to make decisions about which code that it already has to call.
If you show us the real world problem you're trying to solve, we can likely suggest a much better solution than sending a string of Javascript code to the client.
If you really wanted to send a function, you would have to turn it into a string first, send the string, then use the string to turn it back into a function in the client by using a Function object or eval() or creating your own dynamic script tag with inline source.
You can only send strings via socket.io, not functions. That being said, I suggest you to send function names instead.
//server.js
socket.emit('schedule', 'helloworld');
//client.js
function helloworld(){
console.log('hello world');
}
socket.on('schedule',function(name){
window[name](); //hello world
});

Ajax with node.js/jade

I'm searching for a way to use ajax running on node.js, express and jade as template-engine without routing to subpages. I read this: Node, Express, Ajax, and Jade Example
But this doesn't work for me. I don't want to make a route to a partial part of page, so the user could access the partial page. I just want to serve a convertet jade file in a part of the website.
I think about something like this:
$( ".trigger" ).on( "click", function() {
$( ".result" ).load( "ajax/test.jade" );
});
How could I do this without setting a route in node.js so the user could access the subpage without accessing the whole page.
Thank you for your answers.
What if you send the file as a GET parameter:
var jade = require('jade'),
fs = require('fs');
app.get('/ajax', function(req, res) {
fs.readFile(req.query.file, 'utf8', function (err, data) {
if (err) throw err;
var fn = jade.compile(data);
var html = fn({});
res.send(html);
});
});
and send request like
/ajax?file=test.jade
If you do the things like that you will have only one route.
(Still requires a route but) You could set up a route that only provides a valid response if it is an ajax request, and a 4xx if otherwise
app.get('/path', function(req, res) {
if(req.xhr)
{
...
}
});
req.xhr Express docs.
You could place a jade template (or HTML file) in the public folder on your website, assuming you have it set up.
For example, in the app.js:
app.use(express.static(__dirname + '/public'));
Place the template/file in (or any subfolder):
/public/example.html
Then you can use $.get to load the file, like the link you provided:
$.get('/example.html', function(result) {
$('#test').html(result);
});
I have a problem with ajax call
Server side:
router.get('/user/letterlist', function(req, res) {
// ... some operations
res.render('userLetterList', { title: 'test', rows : rows? rows: null, pageCount: pageCount,itemCount: itemCount });
});
Client side index.jade
extends layout
block content
div(id="userLettersList")
button(type="button" class="btn btn-success")
{success}
script.
$(".btn").click(function(e){
e.preventDefault();
$.ajax({
url: "/user/letterlist",
success: function(data){
$("#userLettersList").html(data) ;
}
});
});
client side userLetterList.jade
table(id="UserLetters" class="table table-striped table-bordered")
thead
....
The problem is when push on the button to load data into the div, it will retrieve and show, but the page redirect to nowhere with a blank page, after some m-seconds.

Access file on a Node.js server

If you are familiar with NowJS, one you start an instance of Now on the server, you can access a file located on the server by <script src="http://localhost:8080/nowjs/now.js"></script>
Any ideas on how to implement this?
Thanks,
Mark
There are many static file handler modules already in node, take a look at:
https://github.com/joyent/node/wiki/modules#wiki-web-frameworks-static
Most popular are:
https://github.com/felixge/node-paperboy
and
https://github.com/cloudhead/node-static
Using node static is as simple as:
var static = require('node-static');
var file = new(static.Server)('./public');
require('http').createServer(function (request, response) {
request.addListener('end', function () {
file.serve(request, response);
});
}).listen(8080);

Categories

Resources