Mostrando entradas con la etiqueta NodeJS. Mostrar todas las entradas
Mostrando entradas con la etiqueta NodeJS. Mostrar todas las entradas

Hostear Node.js en Heroku

https://dashboard.heroku.com/apps/gastos-2020/deploy/heroku-git


1. Descargar Heroku Cli
2. cmd > heroku login
3. Crear aplicacion en Heroku (ej, gastos-2020)
4. ir a la carpeta donde está el codigo fuente de la aplicación node.js
5. Deploy:
       git add .
       git commit -am "make it better"

       git push heroku master

Subir archivos junto a otros campos en Angular y NodeJS [** 100% OK **]

setup inicial:

npm install --save express body-parser multer fs path

frontend:

app.component.html

<img src="" name="img" />

<form [formGroup]="form" (ngSubmit)="onSubmit()">
  <div>
    <label for="nombre">Name</label>
    <input type="text" id="nombre" placeholder="Ingrese el nombre" formControlName="nombre">
  </div>
  <div>
    <label for="foto">Foto</label>
    <input type="file" id="foto" (change)="onFileChange($event)" #fileInput>
    <button type="button" (click)="clearFile()">clear file</button>
  </div>
  <button type="submit" [disabled]="form.invalid || loading">Submit</button>
</form>

app.component.ts

import { Component, ElementRef, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClient } from "@angular/common/http";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  form: FormGroup;
  loading: boolean = false;

  @ViewChild('fileInput') fileInput: ElementRef;

  constructor(private fb: FormBuilder, private http: HttpClient) {
    this.createForm();
  }

  createForm() {
    this.form = this.fb.group({
      nombre: ['', Validators.required],
      foto: null
    });
  }

  onFileChange(event) {
    if(event.target.files.length > 0) {
      let file = event.target.files[0];
      this.form.get('foto').setValue(file);
     
      var preview = document.querySelector('img');     
      var reader  = new FileReader();
   
      reader.onloadend = function () {
        preview.src = reader.result;
      }
   
      if (file) {
        reader.readAsDataURL(file);
      } else {
        preview.src = "";
      }

    }
  }

  onSubmit() {
    let formModel = new FormData();
    formModel.append('nombre', this.form.get('nombre').value);
    formModel.append('foto', this.form.get('foto').value);
   
    this.loading = true;

    this.http.post("http://localhost:8080/upload", formModel).subscribe((datos) => {               
      console.log(datos);   
   });     
  }

  clearFile() {
    this.form.get('foto').setValue(null);
    this.fileInput.nativeElement.value = '';
  }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpModule, Http } from '@angular/http';
import { HttpClientModule } from '@angular/common/http';
import { HttpClient } from "@angular/common/http";

import { AppComponent } from './app.component';


@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    ReactiveFormsModule,
    HttpModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }


servidor:

var express = require("express")
    app = express(),
    bodyParser = require("body-parser"),
    multer  = require('multer'),
    fs = require('fs'),
    path = require('path');

var upload  = multer({ storage: multer.memoryStorage() });

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

var router = express.Router();

app.use(function (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, content-type, x-access-token, Authorization');
    res.setHeader('Access-Control-Allow-Credentials', true);             

    next();
});

app.use(router);

router.post('/upload', upload.array('foto'), function(req, res) {
    console.log("archivos son........: " + req.files);
    console.log(req.files[0]);
   
    console.log("el nombre es: " + req.body.nombre);

    var buffer = req.files[0].buffer;
    var magic = buffer.toString('hex', 0, 4);
    var filename = req.files[0].fieldname + '-' + Date.now() + path.extname(req.files[0].originalname);

    fs.writeFile('/temp/' + filename, buffer, 'binary', function (err) {
        if (err) throw err
            res.end('File is uploaded')
    })

    res.send(JSON.stringify({resultado : 'ok'}));       
});

app.listen(8080, function() {
    console.log("Node server running on http://localhost:8080");
});

Subir imagen con express-fileupload en angular y nodejs

index.html

<html>
  <body>
    <form ref='uploadForm'
      id='uploadForm'
      action='http://localhost:8080/upload'
      method='post'
      encType="multipart/form-data">
      <input id="nombre" name="nombre" size=20 >
     
        <input type="file" name="sampleFile" />
        <input type='submit' value='Upload!' />
    </form>   
  </body>
</html>



app.js

const express = require('express');
const fileUpload = require('express-fileupload');
const app = express();

// default options
app.use(fileUpload());

app.post('/upload', function(req, res) {
    console.log(req.body.nombre);
  if (!req.files)
    return res.status(400).send('No files were uploaded.');
 
  let sampleFile = req.files.sampleFile;

  sampleFile.mv('/temp/filename.jpg', function(err) {
    if (err)
      return res.status(500).send(err);

    res.send('File uploaded!');
  });
});

app.listen(8080, function() {
    console.log("Node server running on http://localhost:8080");
});




Authorization token ANGULAR NODEJS con Interceptor http

******* IMPORTANTE!!!! El httpinterceptor se dispara solo si se utiliza la clase HttpClient para invocar al servicio, si se utiliza Http, no se dispara!!! *******

Servidor

app.js

var express = require("express"),
    app = express(),
    bodyParser  = require("body-parser"),
    methodOverride = require("method-override");

app.use(function (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, content-type, x-access-token, Authorization');
    res.setHeader('Access-Control-Allow-Credentials', true); 

    if (req.header('Authorization') == undefined)
        return next();
     
    if (req.header('Authorization') == "Bearer #112222")
    {
        console.log("Autorizado");
        next();
    } else
    {
        console.log("NO autorizado");             
        res.sendStatus(401);
    }     
});

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());

var router = express.Router();

app.use(router);

router.get('/prueba', function(req, res) {
    var p = [{nombre: 'carlos', apellido: 'russo'},
             {nombre: 'karina', apellido: 'ortiz'}];

    res.send(p);
});

app.listen(8080, function() {
  console.log("Node server running on http://localhost:8080");
});


Cliente

app.component.html

<div style="text-align:center">
<h1>Prueba de authentication con token</h1>

<button (click)="metodo1()">Method 1</button>
</div>

app.component.ts

import { Component } from '@angular/core';
import { HttpClient } from "@angular/common/http";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {

  title = 'app';
  constructor(private httpClient: HttpClient) { }

  metodo1(): void { 
      this.httpClient.get("http://localhost:8080/prueba").subscribe(
        success => {
          console.log("Ok!");
          console.log(success);
      }
    );
  }
}


app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { InterceptorHttp } from './interceptorhttp'
import { AppComponent } from './app.component';

@NgModule({
declarations: [
  AppComponent,
],
imports: [
  BrowserModule,
  HttpClientModule
],
providers: [
{
  provide: HTTP_INTERCEPTORS,
  useClass: InterceptorHttp,
  multi: true
}
],
bootstrap: [AppComponent]
})

export class AppModule { }


interceptorhttp.ts

import {Injectable} from "@angular/core";
import {HttpEvent, HttpHandler, HttpInterceptor} from "@angular/common/http";
import {HttpRequest} from "@angular/common/http";
import {Observable} from "rxjs/Observable";
//import {Http, Headers, RequestOptions } from '@angular/http';

@Injectable()
export class InterceptorHttp implements HttpInterceptor {
    constructor() {
    }

    intercept(req: HttpRequest<any>,
               next: HttpHandler):Observable<HttpEvent<any>> {
        console.log("interceptando!!!");

        const customHeaderRequest = req.clone({
            headers: req.headers.set('Authorization', 'Bearer #112222')
        });
     
        console.log(req);

       return next.handle(customHeaderRequest);
    }
}





Angular deploy to Heroku

//solo 1ra vez
heroku git:clone -a gastos-2020

//para subir cambios
git add .
git commit -am "make it better"
git push heroku master

Parametros POST en NodeJS y Angular


Ejemplo 1 (Con formulario):

Cliente:

app.component.html

<form (ngSubmit)="onSubmit()" method="POST">
  Usuario: <input type="text" [(ngModel)]="name" name="name">
  <br>
Password:<input type="text" [(ngModel)]="password" name="password">
  <br>

<input type="submit" value="Enviar" />
</form>

app.component.ts

import { Component } from '@angular/core';
import { DataService } from './data.service';
import { Http, Response } from '@angular/http';
import 'rxjs/add/operator/map';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  constructor(private data : DataService) {}

  title = 'app';
  name: string;
  password: string;

  onSubmit() {
    console.log(this.name + " " + this.password);
 
    this.data.login(this.name, this.password).subscribe((datos) => {         
      console.log(datos);   
   });
  }
}


app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { DataService } from './data.service';

import { HttpModule } from '@angular/http';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  providers: [DataService],
  bootstrap: [AppComponent]
})
export class AppModule { }


data.service.ts

import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class DataService {

  constructor(public http: Http) { }

  login(name: string, password: string) {
    console.log("llamando al servicio");       
 
    return this.http.post("http://localhost:3000/login", {name: name, password: password})     
    .map(res => res.json());       
  } 
}

Servidor

var express=require('express');
var app=express();
var bodyParser = require('body-parser');

app.use(function (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
    res.setHeader('Access-Control-Allow-Credentials', true);
    next();
});

var router=express.Router();
router.use(bodyParser.json());
router.use(bodyParser.urlencoded({extended: false}));

router.get('/', function(req, res) {
    res.send("Hello World!");
 });
router.post('/login',testFunction);

router.get('/prueba', function(req, res) {
    console.log("prueba...");

    res.send(JSON.stringify("ok"));
});

function testFunction(req,res) { 
    var name=req.body.name;
    var password=req.body.password;
 
    console.log("Name:" + name + " Password:" + password);

    res.send(JSON.stringify("ok"));
}

app.use(router);

//module.exports=router;

app.listen(3000, function() {
    console.log("Node server running on http://localhost:3000");
});




Ejemplo 2:


router.post('/competidores/guardar', function (req, res) {
    var nombre = req.body.nombre;
    var direccion = req.body.direccion;
 
    console.log(nombre);

    res.send(nombre);
});


Para testearlo con Postman:
Elegir POST
Luego Body
x-www-form-urlencoded


Ejemplo con insert:

router.post('/competidores/guardar', function (req, res) {
    var body = req.body;
    var resultado = '';

    con.query(
        'INSERT INTO competidor (numero, nombres, apellidos, cedula, apodo, barrio, nacionalidad, direccion, telefono, ' +
               'celular, email, estatura, experiencia, fecha_nacimiento, gimnasio, entrenador, sociedad, peso) ' +
            'VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
            [body.numero, body.nombres, body.apellidos, body.cedula, body.apodo, body.barrio, body.nacionalidad,
             body.direccion, body.telefono, body.celular, body.email, body.estatura, body.experiencia,
             body.fecha_nacimiento, body.gimnasio, body.entrenador, body.sociedad, body.peso],
        function (err, results) { 
            if (err == null)
                resultado = "OK";
            else
                resultado = err;

            console.log(resultado);
        }
    );   

    res.send(resultado);     
});

Parametros GET en NodeJS y Angular

ver: https://scotch.io/tutorials/use-expressjs-to-get-url-and-post-parameters

Servidor:

var express = require("express"),
    app = express(),
    bodyParser  = require("body-parser"),
    methodOverride = require("method-override"); 
 
  app.use(function (req, res, next) { 
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
    res.setHeader('Access-Control-Allow-Credentials', true);
    next();
  });

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());

var router = express.Router();

router.get('/', function(req, res) {
   res.send("Hello World!");
});

router.get('/abc/:id/:id2/:id3', function(req, res) {
    var datos1 = req.params.id;
    var datos2 = req.params.id2;
    var datos3 = req.params.id3;

    console.log(datos1);
    console.log(datos2);
    console.log(datos3);

    res.send(JSON.stringify("ok")); 
});

app.use(router);

app.listen(8080, function() {
    console.log("Node server running on http://localhost:8080");
});


Cliente:

datos.service.ts

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class DatosService {

  constructor(public http: Http) { }

  result:any;

  abc(id1: string, id2: string, id3: string) {         
    return this.http.get("http://localhost:8080/abc/" + id1 + "/" + id2 + "/" + id3)     
    .map(res => res.json());       
  }   
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HttpModule } from '@angular/http';
import { DatosService } from './datos.service';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';
import { ContenidoComponent } from './contenido/contenido.component';

@NgModule({
  declarations: [
    AppComponent,    
    ContenidoComponent
  ],
  imports: [
    BrowserModule,
    HttpModule,
    FormsModule,
    RouterModule.forRoot([
      {path: 'prueba/:id1/:id2/:id3', component: ContenidoComponent}
    ])          
  ],
  providers: [DatosService],
  bootstrap: [AppComponent]
})
export class AppModule { }


app.component.ts

import { Component } from '@angular/core';
import { DatosService } from './datos.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';
  datos : any;
  servidor: string;
  idmantis: number;
  archivos: any;

  constructor(private data : DatosService) {}

  abc(id1:string, id2:string, id3:string) {                
    this.data.abc(id1, id2, id3).subscribe((datos) => {    
      
      console.log(datos);              
    });
}


app.component.html

<h1>Pagina principal</h1>

<button (click)='abc(22, 33, 44)'>Prueba parametros</button>

<router-outlet></router-outlet>







ERROR SyntaxError: Unexpected token in JSON

Si se va a devolver un string, usar la funcion de JSON

res.send(JSON.stringify("respuesta"));

Si se manda un objeto, no es necesario hacerlo:

var datos = {nombre: 'pepe', direccion: 'colonia 1010'};
res.send(datos);


Usar mysql con NodeJS y Angular

Servidor:

package.json

{
  "name": "servidor",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.18.2",
    "express": "^4.16.2",
    "method-override": "^2.3.10",
    "mysql": "^2.15.0"
  }
}

app.js

var express = require("express"),
    app = express(),
    bodyParser  = require("body-parser"),
    methodOverride = require("method-override");

  app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
  });

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());

var router = express.Router();

router.get('/', function(req, res) {
   res.send("Hello World!");
});

router.get('/prueba', function(req, res) {
    var p = [{nombre: 'carlos', apellido: 'russo'},
             {nombre: 'karina', apellido: 'ortiz'}];
 
    res.send(p);
  });

router.get('/sql', function(req, res) {
    var mysql = require('mysql');

    var con = mysql.createConnection({
      host: "Xmantis",
      user: "root",
      password: "p23423423023r2234234rd",
      port: 3360,
      database: "mantis"
    });
   
    con.connect(function(err) {
      if (err) throw err;

      console.log("Connected!");
    });

    con.query(
        'SELECT * FROM X_sector WHERE id > ? and id < ?',[ 4, 20 ],
        function (err, results) {   
            console.log(results);
            res.send(results);
        }
    );     
});

app.use(router);

app.listen(8080, function() {
    console.log("Node server running on http://localhost:8080");
});


Para hacerlo funcionar:

npm install
nodemon app.js (si no esta instalado nodemon, instalarlo con npm install -g nodemon)

y probarlo con:

http://localhost:8080/prueba


Cliente

package.json

{
  "name": "cliente",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build --prod",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^5.0.0",
    "@angular/common": "^5.0.0",
    "@angular/compiler": "^5.0.0",
    "@angular/core": "^5.0.0",
    "@angular/forms": "^5.0.0",
    "@angular/http": "^5.0.0",
    "@angular/platform-browser": "^5.0.0",
    "@angular/platform-browser-dynamic": "^5.0.0",
    "@angular/router": "^5.0.0",
    "core-js": "^2.4.1",
    "rxjs": "^5.5.2",
    "zone.js": "^0.8.14"
  },
  "devDependencies": {
    "@angular/cli": "^1.6.5",
    "@angular/compiler-cli": "^5.0.0",
    "@angular/language-service": "^5.0.0",
    "@types/jasmine": "~2.5.53",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "^4.0.1",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "~1.7.0",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~3.2.0",
    "tslint": "~5.7.0",
    "typescript": "~2.4.2"
  }
}

datos.service.ts

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class DatosService {

  constructor(public http: Http) { }

  result:any;

  desplegar() {           
    return this.http.get("http://localhost:8080/sql")       
    .map(res => res.json());         
  }       
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';

import { HttpModule } from '@angular/http';
import { DatosService } from './datos.service';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpModule
  ],
  providers: [DatosService],
  bootstrap: [AppComponent]
})
export class AppModule { }


app.component.ts

import { Component } from '@angular/core';
import { DatosService } from './datos.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';
  datos : any;

  constructor(private data : DatosService) {}

  desplegar() { 
             
    this.data.desplegar().subscribe((posts) => {       
      console.log(posts);       
      this.datos = posts;
    });
  }   
}


app.component.html

<h1>Prueba MySql</h1>

<button (click)='desplegar()'>Click!!</button>

<ul>
  <li *ngFor="let d of datos">{{ d.nombre }}</li>
</ul>




Servidor web en NodeJS

https://carlosazaustre.es/como-crear-una-api-rest-usando-node-js/

******************************
PARA EL SERVIDOR WEB

cd proj
mkdir web1
cd web1
npm init (crea el archivo package.json. Si se indica --yes, no pide ningun dato, asume los default)
cuando pregunte el nombre del main, en lugar de index ponerle app

npm install express --save
npm install method-override --save
npm install body-parser --save

crear un archivo app.js y agregarle este codigo:
(observar que se agrega el access control allow origin para que
se puedan hacer requests desde localhost:4200)

var express = require("express"),
    app = express(),
    bodyParser  = require("body-parser"),
    methodOverride = require("method-override");

  app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
  });

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());

var router = express.Router();

router.get('/', function(req, res) {
   res.send("Hello World!");
});

router.get('/prueba', function(req, res) {
  var p = [{nombre: 'carlos', apellido: 'russo'},
           {nombre: 'karina', apellido: 'ortiz'}];

  res.send(p);
});

app.use(router);

app.listen(8080, function() {
  console.log("Node server running on http://localhost:8080");
});


luego, ejecutar:

node app.js

y queda corriendo el servidor web.


para que no haya que reiniciarlo cada vez que se hace un cambio, instalar nodemon:

npm install -g nodemon

luego iniciar la aplicacion con nodemon app.js, o simplemente nodemon (ya sabe que es app.js
porque se lo indicamos en el ng init)

para probarlo, ir a http://localhost8080
o a http://localhost:8080/prueba


***********************************




Stack MEAN (MongoDB, Express, Angular, NodeJS) paso a paso

Tutorial:
https://coursetro.com/posts/code/84/Setting-up-an-Angular-4-MEAN-Stack-(Tutorial)


Para ver la consola de chrome: CTRL + SHIFT + I

Para configurar todo por primera vez (esto se hace una sola vez en el pc)

1. Instalar Node.js (con esto se instala tambien npm -Node Package Manager)

2. Abrir cmd

3. Actualizar npm a la ultima version
          npm i -g npm

4. Instalar nodemon
          npm install -g nodemon     (nodemon permite que se actualicen los cambios sin reiniciar)

5. Instalar mongoDB
          npm install mongodb@2.2.33 --save
       
          ** se indica la version porque con la ultima da: TypeError: db.collection is not a function **

6. Instalar angular cli
          npm install @angular/cli -g

7. Instalar express y body parser
          npm install express body-parser --save

8. Instalar Visual Code


Crear un proyecto nuevo

1. mkdir c:\proj

2. cd proj

3. ng new proj1

4. cd proj1

5.  Si aparece el mensaje de actualizacion de npm, actualizarlo a la ultima version
          npm i -g npm

6. ng serve --open      *** el parametro open abre el navegador automaticamente ***

7. Empezar a editar el projecto (click derecho sobre proj1, Open with Code)


*** SI DA ALGUN ERROR ANGULAR CLI ***
npm uninstall @angular/cli
npm install --save-dev @angular/cli@latest
*****************************************


*** EXPLICACION DEL TWO BINDING ***
Sin usar el two binding, puedo setear valores en los atributos del componente y estos se ven reflejados en la pagina. Pero si pongo algun dato en la pagina (ej en un campo de formulario), estos NO se ven reflejados en los atributos del componente.
Para esto es que hay que utilizar el two binding (para esto hay que importar el FormsModule)

Ejemplo 0 - Crear un servidor web que acepte REST con NodeJS

https://carlosazaustre.es/como-crear-una-api-rest-usando-node-js/


Ejemplo 1 - Calculadora

Para poder usar el two way binding:

En app.module.ts:
import { FormsModule } from '@angular/forms';

imports: [
BrowserModule,
FormsModule
]

En app.component.ts:

export class AppComponent {
title = 'Calculadora';

numero1 : number;
numero2 : number;
resultado : number;

click1() {
this.resultado = this.numero1 + this.numero2;
}
}


En app.component.html

(para que haga la suma y no concatene, utilizar el atributo type="number")

<div>
<div>
Numero1: <input [(ngModel)]="numero1" type="number" name="numero1" />
</div>
<div>
Numero2: <input [(ngModel)]="numero2" type="number" name="numero2" />
</div>
<div>
Resultado: <input [(ngModel)]="resultado" type="number" name="resultado" />
</div>
<div>
<button (click)='click1()'>Click!!</button>
</div>
</div>

*** Servicios: dos ejemplos a continuación ***
leer: https://coursetro.com/posts/code/61/Angular-4-Services-Tutorial
Observables: https://codecraft.tv/courses/angular/http/http-with-observables/

Ejemplo 2 - Calculadora usando un servicio para resolver la suma

datos.service.ts

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class DatosService {
constructor(public http: Http) { }

sumar(num1: number, num2: number) {
return (num1 + num2);
}
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
import { DatosService } from './datos.service';
import { HttpModule } from '@angular/http';

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule
],
providers: [DatosService],
bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';
import { DatosService } from './datos.service';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
numero1: number;
numero2: number;
resultado: number;

constructor(private data : DatosService) {
this.numero1 = 5;
this.numero2 = 2;
}

sumar() {
let j = this.data.sumar(this.numero1, this.numero2);

this.resultado = j;
}
}

app.component.html

<div style="text-align:center">
<h1>
{{ title }}
</h1>
</div>


<input [(ngModel)]="numero1" type="number" name="numero1" />
<input [(ngModel)]="numero2" type="number" name="numero2" />

<h1>{{resultado}}</h1>

<button (click)='sumar()'>Click!!</button>




Ejemplo 3 - Servicio obteniendo json de una url

datos.service.ts

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class DatosService {
constructor(public http: Http) { }

result:any;

desplegar() {
return this.http.get("https://jsonplaceholder.typicode.com/posts")
.map(res => res.json());
}
}

app.component.ts

import { Component } from '@angular/core';

import { DatosService } from './datos.service';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private data : DatosService) {
}

desplegar() {
this.data.desplegar().subscribe((posts) => {
console.log(posts);
});
}
}

app.component.html

<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
<h1>
{{ title }}
</h1>
</div>

<button (click)='desplegar()'>Click!!</button>


Ejemplo 4 - Rutas

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
import { DatosService } from './datos.service';
import { HttpModule } from '@angular/http';

import { RouterModule } from '@angular/router';
import { ListadoComponent } from './listado/listado.component';
import { DetallesComponent } from './detalles/detalles.component';

@NgModule({
declarations: [
AppComponent,
ListadoComponent,
DetallesComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot([
{path: 'listado', component: ListadoComponent},
{path: 'detalles/:id', component: DetallesComponent}
])
],
providers: [DatosService],
bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html

<a routerLink="listado">LISTADO</a>

<button routerLink="detalles">Detalles</button>

<router-outlet></router-outlet>

(observar que dentro del tag router-outlet es donde se desplegara el contenido de cada ruta)

listado.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-listado',
templateUrl: './listado.component.html',
styleUrls: ['./listado.component.css']
})
export class ListadoComponent implements OnInit {

constructor() { }

ngOnInit() {
}

}

listado.component.html

<p>
listado works!
</p>

detalles.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-detalles',
templateUrl: './detalles.component.html',
styleUrls: ['./detalles.component.css']
})
export class DetallesComponent implements OnInit {

constructor() { }

ngOnInit() {
}

}

detalles.component.html

<p>
detalles works!
</p>




MongoDB

ir a pagina mongodb.com y bajar mongoDB
https://www.mongodb.com/download-center#community

crear carpeta c:\data\db

iniciar:
C:\Program Files\MongoDB\Server\3.6\bin>mongod.exe

en otra ventana iniciar:
C:\Program Files\MongoDB\Server\3.6\bin>mongo.exe

en la consola que se abre:
use mean
db.users.insert({"name": "John Doe"})

En la consola del principio:
cd proj1
npm install mongodb@2.2.33 --save

crear carpeta proj1\server\routes

crear archivo api.js

ng g service data
(crea el archivo data.service.ts)

**** CREAR UN SERVICIO EN ANGULAR ****

**** CREAR UN NUEVO COMPONENTE ****
ng generate component nombre-del-componente
*****************************************

para compilar:
ng build

para iniciarlo con nodemon:
nodemon server (server es el nombre del .js)

para iniciarlo sin nodemon:
node server