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


Edicion multicamara con Sony Vegas

Ctrl+A (seleccionar todo)
Tools/Multicamera/Create multicamera track
Tools/Multicamera/Enable multicamera editing


Clase ExcelLogica


using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.IO;
using System.Reflection;

namespace Logica.Excel
{
    public static class ExcelLogica
    {
        public static List<object> Leer(string archivo)
        {
            var lista = new List<object>();

            List<List<string>> samples = new List<List<string>>();
            try
            {
                int selCount = 0;
                var document = SpreadsheetDocument.Open(archivo, false);
                var workbookPart = document.WorkbookPart;
                var sheets = workbookPart.Workbook.Descendants<Sheet>();
                var fila = 1;               

                foreach (Sheet sheet in sheets)
                {
                    var workSheet = ((WorksheetPart)workbookPart.GetPartById(sheet.Id)).Worksheet;
                    var sheetData = workSheet.Elements<SheetData>().First();
                    List<Row> rows = sheetData.Elements<Row>().ToList();

                    var columnas = rows.ElementAt(0).Elements<Cell>().Count();
                    var b = new string[columnas];
                   
                    foreach (Row row in rows)
                    {
                        var indice = 0;

                        b = new string[columnas];

                        foreach (Cell c in row.Elements<Cell>())
                        {
                            var value = "";

                            if (c != null)
                            {
                                value = c.InnerText;

                                if (c.DataType != null)
                                {
                                    switch (c.DataType.Value)
                                    {
                                        case CellValues.SharedString:

                                            // For shared strings, look up the value in the
                                            // shared strings table.
                                            var stringTable =
                                                workbookPart.GetPartsOfType<SharedStringTablePart>()
                                                .FirstOrDefault();

                                            // If the shared string table is missing, something
                                            // is wrong. Return the index that is in
                                            // the cell. Otherwise, look up the correct text in
                                            // the table.
                                            if (stringTable != null)
                                            {
                                                value =
                                                    stringTable.SharedStringTable
                                                    .ElementAt(int.Parse(value)).InnerText;
                                            }
                                            break;

                                        case CellValues.Boolean:
                                            switch (value)
                                            {
                                                case "0":
                                                    value = "FALSE";
                                                    break;
                                                default:
                                                    value = "TRUE";
                                                    break;
                                            }
                                            break;
                                    }
                                }

                                b[indice] = value;
                                indice++;
                            }
                        }

                        fila++;
                        lista.Add(b);
                    }
                }
            } catch (Exception ex)
            {}

            return lista;
        }

        public static byte[] GenerarOpenXml(DataTable t, string autofiltro)
        {
            MemoryStream stream = new MemoryStream();

            using (SpreadsheetDocument myWorkbook =
                    SpreadsheetDocument.Create(stream,
                    SpreadsheetDocumentType.Workbook, true))
            {
                WorkbookPart workbookPart = myWorkbook.AddWorkbookPart();
                var worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
                string relId = workbookPart.GetIdOfPart(worksheetPart);

                var fileVersion = new FileVersion { ApplicationName = "Microsoft Office Excel" };

                var sheets = new Sheets();
                var sheet = new Sheet { Name = t.TableName, SheetId = 1, Id = relId };
                sheets.Append(sheet);

                SheetData sheetData = new SheetData(CreateSheetData(t));

                var workbook = new Workbook();
                workbook.Append(fileVersion);
                workbook.Append(sheets);
                var worksheet = new Worksheet();
                worksheet.Append(sheetData);

                AutoFilter autoFilter1 = null;

                if (autofiltro != null)
                {
                    autoFilter1 = new AutoFilter() { Reference = autofiltro };
                    worksheet.Append(autoFilter1);
                }

                worksheetPart.Worksheet = worksheet;
                myWorkbook.WorkbookPart.Workbook = workbook;
                myWorkbook.WorkbookPart.Workbook.Save();
                myWorkbook.Close();

                return stream.ToArray();
            }
        }

        public static byte[] GenerarOpenXml<T>(this IEnumerable<T> collection, string autofiltro)
        {
            var t = ToDataTable(collection, "Subdiario");

            return GenerarOpenXml(t, autofiltro);
        }

        public static MemoryStream BuildExcel(DataTable dataTable, string autofiltro)
        {
            MemoryStream stream = new MemoryStream();

            using (SpreadsheetDocument myWorkbook =
                    SpreadsheetDocument.Create(stream,
                    SpreadsheetDocumentType.Workbook, true))
            {
                WorkbookPart workbookPart = myWorkbook.AddWorkbookPart();
                var worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
                string relId = workbookPart.GetIdOfPart(worksheetPart);

                var fileVersion = new FileVersion { ApplicationName = "Microsoft Office Excel" };

                var sheets = new Sheets();
                var sheet = new Sheet { Name = dataTable.TableName, SheetId = 1, Id = relId };
                sheets.Append(sheet);

                SheetData sheetData = new SheetData(CreateSheetData(dataTable));

                var workbook = new Workbook();
                workbook.Append(fileVersion);
                workbook.Append(sheets);
                var worksheet = new Worksheet();
                worksheet.Append(sheetData);

                AutoFilter autoFilter1 = null;

                if (autofiltro != null)
                {
                    autoFilter1 = new AutoFilter() { Reference = autofiltro };
                    worksheet.Append(autoFilter1);
                }


                worksheetPart.Worksheet = worksheet;
                myWorkbook.WorkbookPart.Workbook = workbook;
                myWorkbook.WorkbookPart.Workbook.Save();
                myWorkbook.Close();

                return stream;
            }
        }

        private static List<OpenXmlElement> CreateSheetData(DataTable dataTable)
        {
            List<OpenXmlElement> elements = new List<OpenXmlElement>();

            var rowHeader = new Row();
            Cell[] cellsHeader = new Cell[dataTable.Columns.Count];
            for (int i = 0; i < dataTable.Columns.Count; i++)
            {
                cellsHeader[i] = new Cell();
                cellsHeader[i].DataType = CellValues.String;
                cellsHeader[i].CellValue = new CellValue(dataTable.Columns[i].ColumnName);
            }
            rowHeader.Append(cellsHeader);
            elements.Add(rowHeader);

            foreach (DataRow rowDataTable in dataTable.Rows)
            {
                var row = new Row();
                Cell[] cells = new Cell[dataTable.Columns.Count];

                for (int i = 0; i < dataTable.Columns.Count; i++)
                {
                    cells[i] = new Cell();

                    if (dataTable.Columns[i].DataType == System.Type.GetType("System.Decimal"))
                        cells[i].DataType = CellValues.Number;
                    else if (dataTable.Columns[i].DataType == System.Type.GetType("System.DateTime"))
                        cells[i].DataType = CellValues.Date;
                    else
                        cells[i].DataType = CellValues.String;

                    cells[i].CellValue = new CellValue(rowDataTable[i].ToString());
                }
                row.Append(cells);
                elements.Add(row);
            }
            return elements;
        }

        public static DataTable ToDataTable<T>(this IEnumerable<T> collection, string tableName)
        {
            DataTable tbl = ToDataTable(collection);
            tbl.TableName = tableName;
            return tbl;
        }

        public static DataTable ToDataTable<T>(this IEnumerable<T> collection)
        {
            DataTable dt = new DataTable();
            Type t = typeof(T);
            PropertyInfo[] pia = t.GetProperties();
            object temp;
            DataRow dr;

            for (int i = 0; i < pia.Length; i++)
            {
                dt.Columns.Add(pia[i].Name, Nullable.GetUnderlyingType(pia[i].PropertyType) ?? pia[i].PropertyType);
                dt.Columns[i].AllowDBNull = true;
            }

            //Populate the table
            foreach (T item in collection)
            {
                dr = dt.NewRow();
                dr.BeginEdit();

                for (int i = 0; i < pia.Length; i++)
                {
                    temp = pia[i].GetValue(item, null);
                    if (temp == null || (temp.GetType().Name == "Char" && ((char)temp).Equals('\0')))
                    {
                        dr[pia[i].Name] = (object)DBNull.Value;
                    }
                    else
                    {
                        dr[pia[i].Name] = temp;
                    }
                }

                dr.EndEdit();
                dt.Rows.Add(dr);
            }
            return dt;
        }
    }

}