Leer una imagen de mysql y mostrarla en Angular

en este ejemplo, foto es el campo leido de mysql, tiene un atributo data que es la imagen codificada.

var preview = document.querySelector('img');                           
var arrayBufferView = new Uint8Array(foto.data);
var blob = new Blob( [ arrayBufferView ], { type: "image/jpeg" } );
var urlCreator = window.URL;
var imageUrl = urlCreator.createObjectURL(blob);       
preview.src = imageUrl;



Validaciones custom con Angular 5


app.component.html

<form [formGroup]="agendaForm" (ngSubmit)="submit()">
  <input formControlName="usuario">
  <input formControlName="telefono">

  <div *ngIf="agendaForm.get('usuario').errors">
     <div *ngIf="agendaForm.get('usuario').errors['required']">
          Nombre de usuario es requerido
     </div>
  </div>

  <div *ngIf="!agendaForm.valid">
       Hay errores en el form!!!
  </div>

  <button type="submit" [disabled]="!agendaForm.valid">Enviar</button>
</form>

app.component.ts

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormControl, ValidatorFn, AbstractControl } from '@angular/forms';

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

  agendaForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.crearForm();
  }

  crearForm() {
    this.agendaForm = this.fb.group({
      usuario: ['texto precargado', Validators.required],
      telefono: ['', Validators.compose(
                        [Validators.required,
                         this.telefonoValidator(/^[679]{1}[0-9]{8}$/)
                        ]
                      )
                ]             
    });
  }

  telefonoValidator(telefonoExp: RegExp): ValidatorFn {
    return (control: AbstractControl): {[key: string]: any} => {
      const telefono = telefonoExp.test(control.value);
      return !telefono ? {'telefonoNumber': {value: control.value}} : null;
    };
  }
}

app.module.ts

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

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

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

Crear formulario con FormBuilder ReactiveForms en Angular 5

app.module.ts

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

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


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


app.component.ts

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormControl, ValidatorFn, AbstractControl } from '@angular/forms';

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

  loginForm: FormGroup;

  constructor(private fb: FormBuilder) {
    this.crearForm();
  }

  crearForm() {
    this.loginForm = this.fb.group({
      usuario: ['texto precargado', Validators.required],
      password: ['']               
    });
  }
}

app.component.html

<form [formGroup]="loginForm" (ngSubmit)="submit()">
  <input formControlName="usuario">
  <input formControlName="password">

  <button type="submit" [disabled]="!loginForm.valid">Enviar</button>
</form>

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");
});

Preview image con html5 y filereader y html5

html:

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

<form [formGroup]="form" (ngSubmit)="onSubmit()">
    <input type="file" id="avatar" (change)="onFileChange($event)" #fileInput>
    <button type="submit">Submit</button>
</form>


Angular:

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

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");
});




Instalacion de Crystal Reports en Visual Studio 2017

http://www.crystalreports.com/crystal-reports-visual-studio/

Entrar a este link, registrarse, y hacer click en "Installation package for visual studio ide"
Esto baja el paquete: CRforVS_13_0_22.exe

**** IMPORTANTE EJECUTARLO COMO ADMINISTRADOR Y CON TODOS LOS VISUAL STUDIO CERRADOS ****

**** DEJAR MARCADO 64bit RUNTIME ****

fuente: https://wiki.scn.sap.com/wiki/display/BOBJ/Crystal+Reports%2C+Developer+for+Visual+Studio+Downloads

Authorization en WebApi con ActionFilterAttribute

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;


namespace Servicios
{
    public class FiltroAuthorization : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            // pre-processing
            Debug.WriteLine("ACTION 1 DEBUG pre-processing logging");
        }

        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            var objectContent = actionExecutedContext.Response.Content as ObjectContent;
            if (objectContent != null)
            {
                var type = objectContent.ObjectType; //type of the returned object
                var value = objectContent.Value; //holding the returned value
            }

            Debug.WriteLine("ACTION 1 DEBUG  OnActionExecuted Response " + actionExecutedContext.Response.StatusCode.ToString());
        }
    }
}


En WebApiConfig.cs

config.Filters.Add(new FiltroAuthorization());





Layout de dos columnas con encabezado y pie con div y css

estilos.css

*** en el caso en que se utilice en Angular, el body no ponerlo (iria en el index.html) ***

body {
padding: 0; margin: 0;
}

.encabezado
{
float: top;
width: 100%;
height: 14%;
}

.titulo
{
background-color: lightgray;
padding: 10px;
height: 100%
}

.principal
{
background-color: magenta;
width: 100%;
height: 86%;
}

.navegacion
{
float: left;
background-color: yellow;
width: 15%;
height: 92%;
overflow-y: auto;
}

.contenido
{
float: left;
background-color: orange;
width: 85%;
height: 92%;
overflow-y: auto;
}

.pie
{
background-color: red;
color: yellow;
font-weight: bold;
width: 100%;
height: 100%;
}

.seccion
{
padding: 10px;
}

.mensajes
{
background-color: pink;
color: blue;
height: 100%;
}

.menu
{
padding: 1px;
}

index.html

<div id="contenedor" style="height: 100vh">  
  <div class="encabezado">
    <div class="titulo">
      <div align="right">
        Encabezado
      </div>
    </div>
  </div>

  <div class="principal">   
    <div class="navegacion">
      <div class="menu">
        Menu
      </div>
    </div>

    <div class="contenido">     
      <div class="seccion">     
        Contenido
      </div>
    </div>

    <div class="pie">
      <div class="mensajes">
        Mensajes
      </div>
    </div>
  </div> 
</div>