0

I need to retrieve and display data from my node/exprss file (app.js) and display it on my index.html. I make an ajax request to localhost:3000/turtles in my frontend.js file, but this is where I have cross domain issues.

APP.JS FILE

var express = require('express');
var app = express();

app.get('/turtles', function(req, res){

    var turtles = {
      message: "success",
      data: [
        {
          name: "Raphael",
          favFood: "Pizza"
        },
        {
          name: "Leonardo",
          favFood: "Pizza"
        },
        {
          name: "Donatello",
          favFood: "Pizza"
        },
        {
          name: "Michelangelo",
          favFood: "Pizza"
        }
      ]
    };

    res.send(turtles.data[0].name);
});

app.listen(10000, function(){
    console.log("Port is on 10000!");
});

FRONTEND.JS

  $(document).ready(function(){

    var name;

    var myQueryUrl = "http://localhost:10000/turtles";

    $.ajax({url: myQueryUrl, method: 'GET'}).done(function(response){

            name = response.data[0].name;

            $('.DTurtles').append($('<p>' + name + '</p>'));

    }); 

});

I tried using sendFile('index.html') but I think that's not what I am looking for. Doing this will load my html on homepage (localhost:3000/), but I need to dynamically pull data from the turtles object (the names), and then display it on my html.

When I use the sendFile('index.html'), I get the following error when I load the page localhost:3000

TypeError: path must be absolute or specify root to res.sendFile
   at ServerResponse.sendFile (C:\Users\hen\Desktop\Camp\assignments\optionalNodeAssignment\node_modules\express\lib\response.js:404:11)
   at C:\Users\hen\Desktop\Camp\assignments\optionalNodeAssignment\server.js:29:8
   at Layer.handle [as handle_request] (C:\Users\hen\Desktop\Camp\assignments\optionalNodeAssignment\node_modules\express\lib\router\layer.js:95:5)
   at next (C:\Users\hen\Desktop\Camp\assignments\optionalNodeAssignment\node_modules\express\lib\router\route.js:131:13)
   at Route.dispatch (C:\Users\hen\Desktop\Camp\assignments\optionalNodeAssignment\node_modules\express\lib\router\route.js:112:3)
   at Layer.handle [as handle_request] (C:\Users\hen\Desktop\Camp\assignments\optionalNodeAssignment\node_modules\express\lib\router\layer.js:95:5)
   at C:\Users\hen\Desktop\Camp\assignments\optionalNodeAssignment\node_modules\express\lib\router\index.js:277:22
   at Function.process_params (C:\Users\hen\Desktop\Camp\assignments\optionalNodeAssignment\node_modules\express\lib\router\index.js:330:12)
   at next (C:\Users\hen\Desktop\Camp\assignments\optionalNodeAssignment\node_modules\express\lib\router\index.js:271:10)
   at expressInit (C:\Users\hen\Desktop\Camp\assignments\optionalNodeAssignment\node_modules\express\lib\middleware\init.js:33:5)

When I try the res.send(turtles.data.name), and I click the button on my html page to make the ajax request and try to display names I get the error:

XMLHttpRequest cannot load http://localhost:10000/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

AlainIb, suggested I just return the entire turtle object and not just turtle.name. He also suggested I create a good path file like so

router.get('/', function (req, res, next) {
   res.sendFile(path.join(__dirname, '../', '../', 'client', 'index.html'));
});

I have all my files in the same directory. Can someone explain what the syntax above does. Why is it router.get and not app.get and particularly explain this part

res.sendFile(path.join(__dirname, '../', '../', 'client', 'index.html'));

I also read that I should allow CORS by doing something like the following

app.all('/', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
 });

app.get('/', function(req, res, next) {
  // Handle the get for this route
});

app.post('/', function(req, res, next) {
 // Handle the post for this route
});

but I have no idea what all this does. Where does the next parameter in the app.all function come in from, and what is res.header? Will either of these solutions resolve my cross domain issues?

H. Lee
  • 67
  • 1
  • 9
  • What errors do you get? – JJJ Nov 26 '16 at 20:12
  • this can't work `res.send(turtles.data.name);` because `turtles.data` is an array so you need to send one of the item like `turtles.data[0].name` – AlainIb Nov 26 '16 at 20:21
  • yes but I have a loop in my ajax call. Would I have to somehow increment the index counter every time the function is called? – H. Lee Nov 26 '16 at 22:20

1 Answers1

0

You have to use this syntax to create good path to file

app.get('/', function (req, res, next) {
   // path.join use the good separator accroding to your OS ( \ or / )
   res.sendFile(path.join(__dirname, '../', '../', 'client', 'index.html'));
});

for example if you have folder like this :

  • /server/api/SERVERFS.JS
  • /client/index.html

Node side

// return all the data array ( remove ".name" )
app.get('/', function (req, res) {
      res.send(turtles.data);
});

Angular side

function displayTurtles(){  

    var emptyArray = [];

    var myQueryUrl = "http://localhost:10000/";

    $.ajax({url: myQueryUrl, method: 'GET'}).done(function(response){
        // if you want all the data no need to iterate over it, just reference it
        emptyArray = response.data;    
        console.log("response:");
        console.log(emptyArray);
    });
    // this log will be empty because it will be loged before thath the server return the array data, don't forget ajax in asyncrhonus
    console.log("useless log":emptyArray);
    // if you need do to other thing with emptyArray call a function her   
    doStuff(emptyArray );
}

you should have in your console : console.log("useless log":...); then console.log("response:"); the ajax return take time and the line after the call are executed immediatly, it don't wait the response

AlainIb
  • 4,544
  • 4
  • 38
  • 64
  • Can you please explain this syntax: path.join(__dirname, '../', '../', 'client', 'index.html')); All my files are in the same directory by the way. – H. Lee Nov 28 '16 at 03:38
  • also in your example, you have the ajax call in the same file as the code with the express server. I have mine in two separate files. Should they be in separate files? – H. Lee Nov 28 '16 at 03:42
  • Also, why do you have router.get instead in app.get in this part: router.get('/', function (req, res, next) { – H. Lee Nov 28 '16 at 03:45
  • this `syntax: path.join(__dirname, '../', '../', 'client', 'index.html'));` create the following path `../../client/index.html` but if you have every thing in the same path no need to it ( but better to separate angulars files from node files from your server files. use `sendFile('./index.html')`. i edit the answer, the two codes is not in the same file – AlainIb Nov 28 '16 at 08:03
  • for the `router.get()` stay with `app.get()`. it is the same thing approximatly ( see more her http://expressjs.com/en/guide/routing.html) – AlainIb Nov 28 '16 at 08:12