0

New to AngularJS and Node.js. Please advise.

Because the data I want to display on the page takes quite some time to load. I decide to load the fast data from database_1 first, and then get the slow response from database_2 later. Here is my AngularJS:

var app = angular.module('myApp', [

]);

app.factory('rateFactory', function ($http) {
    return $http.get("localhost/rate"); // api or node.js to return only issueId and rate
})

app.controller('SignupController', function ($scope, $http, $filter, rateFactory) {
    // Display most of the content first
    $scope.showData = function () {
        $http.get("localhost/signup") // api or node.js
        .success(function (response) {
            $scope.Signups = response;

            $scope.curPage = 0;
            $scope.pageSize = 25;
            $scope.numberOfPages = function () {
                return Math.ceil($scope.Signups.length / $scope.pageSize);
            };
        })
        .error(function (data, status, headers, config) {
            alert(status);
        });
    }

    // Display slow response, Rate, later based on the issueId
    $scope.showRate = function (issueId) {
        rateFactory
        .success(function (data) {
            document.getElementById(issueId).innerHTML = data.find(x => x.IssueID === issueId).Rate;
        })
        .error(function (data, status, headers, config) {
            //alert(status);
        });
    }
});

I wonder whether there is any better way to do it. This my first question. Next question is about Node.js. If I get the data from ashx or api, it returns the data without any problem. But when using Node.js for both calls, it's a hit and miss. Sometimes it works fine, but most of the time, the 2nd call fails. Am I doing something wrong? Both returns the data perfectly if calling individually. Here is the node.js code:

var express = require('express');
var http = require('http');
var app = express();
var usp2Json = require('./lib/usp2Json.js');

app.get('/iisnode/myApp/signup', function(req, res) {
    usp2Json.getJsonFromStoredProc('stroedprocToGetSignup', req, res);
});

app.get('/iisnode/myApp/rate', function(req, res) {
    usp2Json.getJsonFromStoredProc('stroedprocToGetRate', req, res);
})

var server = http.createServer(app);
var port = process.env.PORT || 593;
server = app.listen(port, function() {
    console.log('Server is running...');
});

usp2Json.js is a custom module to get data from SQL Server with a stored procedures:

exports.getJsonFromStoredProc = function(storedproc, req, res) {
var sql = require("mssql");
var express = require('express');
var app = express();

res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');

// config database
var config = {
    user: 'username',
    password: 'password',
    server: 'servername',
    database: 'databasename',
};

// connect to database
sql.connect(config, function(err) {
    if(err) console.log(err);

    // create Request object
    var request = new sql.Request();

    // query to the database and get the records
    request.query(storedproc, function(err, recordset) {
        if(err) 
            console.log(err);

        // send records as a response
        res.send(recordset);
    });
});
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Weihui Guo
  • 3,669
  • 5
  • 34
  • 56

2 Answers2

0

One suggestion I have is to get rid of:

document.getElementById(issueId).innerHTML = data.find(x => x.IssueID === issueId).Rate;

And use regular Angular 2 way data binding, and bind your #issueId element to a $scope.issueId scope variable, and update the scope variable on call success. The way it is done right now is sort of an anti-pattern.

In terms of the NodeJS API call, you will need to show us what the route handler i.e. usp2Json.getJsonFromStoredProc does in it's code. Otherwise your code looks perfectly fine

nikjohn
  • 20,026
  • 14
  • 50
  • 86
  • Thank you for your prompt reply. Question updated with usp2Json code. – Weihui Guo Sep 30 '16 at 14:07
  • Not sure how I can use 2 way data binding since the result is display using ng-repeat for , not input/textarea. The factory only returns the issueId and rate. – Weihui Guo Oct 06 '16 at 01:13
0

In terms of the NodeJS API call, the issue is actually the SQL Server connection. When I looked at console.log, it doesn't give me enough information, but simply says "Server is running". I had to add a line to get the details of error:

request.query(storedproc, function (err, recordset) {
        if (err) {                
            fs.appendFile("path"+ datetime+".txt", time + " Error on executing " + storedproc + " - " + err + " \r\n")
            //throw (err);
        }

        // send records as a response
        res.send(recordset);
    });

This gives me "ConnectionError: Connection is closed.". With this information, I was able to find the solution from here:

https://github.com/patriksimek/node-mssql/issues/138

and answer from Stackoverflow: How can I use a single mssql connection pool across several routes in an Express 4 web application?

Community
  • 1
  • 1
Weihui Guo
  • 3,669
  • 5
  • 34
  • 56