2

I would like to move AngularJS project to Angular Universal.

In AngularJS I had $http requests using PHP. For example I had the following code in Services:

this.getNewItems = function () {

    var request = $http({
        method: "GET",
        url: "PHP/newitems.php",
        params: {
            number: "3"
        }
    });

    return ( request.then(handleSuccess, handleError) );

};

Now as I use Node.js with Universal I would like to use Http request with Node.js.

So in component's constructor I should use the construction:

export class HomeComponent {
  mydata: any = {};

  constructor(http:Http) {

    http.get('??????').subscribe(data => {
      this.mydata = data;

    });
  }
}

If I would use JSON-file then I have found many examples like this:

http.get('test.json').subscribe(data => {
    this.mydata = data;
});

However all my data is in existing MySQL database. So I would like to understand how I can reach my data in database.

I have already installed npm MySql component by

npm install mysql

I have found that a connection with Node.js is setting by:

    var mysql = require('mysql');

    var connection = mysql.createConnection({
        host     : 'host',
        user     : 'user',
        password : 'password',
        database : 'dbname'
    });

    connection.connect(function(err) {
        // in case of error
        if(err){
            console.log(err.code);
            console.log(err.fatal);
        }
    });

If I use this connection code in Component's constructor then some errors return, like

ERROR in ./~/mysql/lib/Connection.js
Module not found: Error: Can't resolve 'net'

So how I can integrate the connection code with http.get() request?

Thanks a lot.

Addition: now I came to this (it concerns my starter project for Angular Universal https://github.com/angular/universal-starter):

  1. In Component I use the following code:

    export class HomeComponent {

        mydata:any = [];
    
        constructor(public model: ModelService) {
    
         this.model.get('/api/getmydata')
            .subscribe(data => {
    
              this.mydata = data;
              console.log("My data: " + this.mydata);
        });
        } 
    }
    

2.In backend/api.ts I've added:

router.route('/getmydata')
      .get(function(req, res) {

        setTimeout(function() {
          res.json(Mydata);
        }, 0);
}

If Mydata is a JSON then all works properly and I receive the data. However I would like to connect to MySQL database. So I add a connection code:

router.route('/getmydata')
          .get(function(req, res) {

        var mysql = require('mysql');

        var connection = mysql.createConnection({
          host     : 'localhost',
          user     : 'root',
          password : 'root',
          database : 'mydatabase',
          port: '8889'
        });

        connection.connect(function(err) {
          if (err) {
            console.log("Error connecting to DB: " + err);
            throw err;
          }
        });
...

}

Here I receive errors:

TypeError: Cannot read property 'on' of undefined
        at Protocol._enqueue (/Applications/MAMP/htdocs/Angular2/myproject/node_modules/mysql/lib/protocol/Protocol.js:152:5)
...

Then

Error connecting to DB: Error: Connection lost: The server closed the connection.

If anyone knows how to fix the connection to database I would highly appreciate the advice.

Kirill Ch
  • 5,496
  • 4
  • 44
  • 65

2 Answers2

1

When bundling with node as target, webpack provides an option to customize node environment. The default configuration is:

node: {
  console: false,
  global: true,
  process: true,
  Buffer: true,
  __filename: "mock",
  __dirname: "mock",
  setImmediate: true
}

As you can notice, webpack's default node environment configuration doesn't take libraries such as 'net' under consideration. Adding net library to node environment properties in your server webpack configuration (which is targeted to node) should help (probably webpack.config.js):

node: {
  // your existing props
  net: false
}

The reason I chose to set the value to false is trying to follow the code that resolves these properties. The possible values are documented, but there's not enough documentation regarding what each value means in case of custom properties. Basically (as far as I understand it), false means there's no need in a browser version or a mock of 'net', you need the module itself because the bundle runs in node.

Reuven Chacha
  • 879
  • 8
  • 20
0

The error

TypeError: Cannot read property 'on' of undefined ... 

may occur if Zone.js has an incorrect version or doesn't install properly.

I have found that I received a Warning:

angular2-universal@2.1.0-rc.1 requires a peer of zone.js@~0.6.21 but none was installed. 

So the command to install Zone.js is:

npm install zone.js@0.6.21

Now I am receiving the data from MySQL database successfully.

The complete code is:

    router.route('/newvideos')
          .get(function(req, res) {

            var mysql = require('mysql');

            var connection = mysql.createConnection({
              host     : 'localhost',
              user     : 'root',
              password : 'root',
              database : 'myDB',
              port: '8889'
            });

            connection.connect(function(err) {
              if (err) {
                console.log("Error connecting to DB: " + err);
                throw err;
              }
            });

            connection.query("SELECT * FROM table", function(err, rows, fields) {
              if (err) {
                console.log("Error executing query: " + err);
                throw err;
              }

              connection.end();

              setTimeout(function() {
                res.json(rows);
              }, 0);
         });

     })

HOWEVER!!! I have found that after this the server rendering with using *ngFor stops working!

In HTML-template I have seen only:

 <!--template bindings={}-->

I played with this error on simple JSON return, without connection to database. So I have found that even if I return JSON server rendering stops working. Then I have installed Zone.js without version:

npm install zone.js

and again started returning JSON. At this case server rendering began working properly. But when I have started making connection to MySQL the first original error has occured.

In my case now I have either a connection to MySQL or server rendering. Not both at one time.

If anyone knows how to fix this I'll appreciate the advice. Thank you.

Addition: I have found the solution. See Due to Zone.js in Angular Universal server rendering stops working. How to fix?

Community
  • 1
  • 1
Kirill Ch
  • 5,496
  • 4
  • 44
  • 65