简体   繁体   中英

Angular page not showing JSON data from Node backend

I'm totally new to modern web development and have been learning the MEAN stack from online tutorials. I'm just writing a simple todo app that allows CRUD operations. This is with the MEAN stack (Mongo database via Mongolab) and npm and bower as package managers - no scaffolding tools or cloning an existing app. This is my first time with Node and Angular.

I'm running into problems with displaying my HTML page using Angular. Here are the relevant files:

app.js for the backend (including only the relevant sections):

var express = require('express');
var path = require('path');
var app = express();
var morgan = require('morgan');
var db = require('./db');
var bodyParser = require('body-parser');

app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({'extended' : 'true'}));

require('./backend/todo_rest')(app);

module.exports = app;

todo_rest.js :

var TodoSchema = require('./todo_schema');
var path = require('path');

module.exports = function(_app) {
    _app.get('/api/todos', function(req, res) {
         TodoSchema.find({}, function(err, todos) {
            console.log('API GET; data: ' + todos);
            if(err)
                return res.status(500).send("The todos could not be retrieved from the database!");
            return res.json(todos);
        });
    });

    _app.get('*', function(req, res){
         res.sendFile(path.resolve(__dirname + '/../client/views/index.html'));
     });
};

app.js for the front end:

var app = angular.module('todosApp', []);

app.controller('todosController', function($scope, $http) {
    $scope.todos = {};

    $http({
        method: 'GET',
        url: '/api/todos'
    }).then(function (success) {
        console.log(success.data);
    }, function (error) {
        console.log('Angular GET error: ' + error.data);
    });
});

and index.html :

<!DOCTYPE html>
<html ng-app="todosApp">
<head>
    <meta charset="UTF-8">
    <title>Todos App</title>
    <script src="../../bower_components/jquery/dist/jquery.min.js"></script>
    <script src="../../bower_components/angular/angular.min.js"></script>
    <script src="../app.js"></script>     // <-- this is the frontend's app.js
</head>
<body ng-controller="todosController">
<div>
    <span>Total: {{todos.length}}</span>
    <ul ng-repeat="todo in todos">
        <li>Name: {{todo.title}}, {{todo.completed}}</li>
    </ul>
</div>
</body>
</html>

Although I do want to support full CRUD, right now I just want the HTML to display all the todos from the database. Here are the current problems:

  • When I launch the page via localhost:3000 , I get the HTML but Angular elements like {{todos.length}} are displayed as is, instead of being replaced by the evaluated values. Basically, when I launch that page, I want all the todos to be displayed as a list by calling the /api/todos endpoint that I've exposed in my backend. I've checked that the console.log in the frontend's app.js isn't triggered.
  • When I launch localhost:3000/api/todos , the JSON result is displayed in the browser instead of any HTML. Do I need to use routing in Angular to display a different view for each end point in the same page?

You have not configured your Express server to serve static content, that's why your browser is not able to load app.js . Hence, angular app is not initialized.

Use express.static to load static content.

{{todos.length}} are displayed as is, instead of being replaced by the evaluated values.

If you see this, it means your angularjs app is not bootstraped successfully. See errors at your console for further fix actions.

add app.use(express.static(__dirname)); to your app.js(nodejs) in order to serve static files.

I want all the todos to be displayed as a list by calling the /api/todos

you have to set result from $http.get to $scope.todos

$http({
  method: 'GET',
  url: '/api/todos'
}).then(function (success) {
  console.log(success.data);
  $scope.todos = success.data;      // <-------- set result to $scope.todos
}, function (error) {
  console.log('Angular GET error: ' + error.data);
});

move ng-repeat to li

<ul>
    <li ng-repeat="todo in todos">Name: {{todo.title}}, {{todo.completed}}</li>
</ul>

When I launch localhost:3000/api/todos, the JSON result is displayed in the browser instead of any HTML. Do I need to use routing in Angular to display a different view for each end point in the same page?

You mean access localhost:3000/api/todos at your browser directly? you don't have to this, $http.get will do the work and retrieve the result. And currently you don't need routing since you just have one simple page.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM