AXIOS

Instalar axios

Importar en el fichero ts donde lo vayas a usar

import axios from 'axios';
axios.get(url)

axios.post(url, body)

axios.put(url, body)

axios.delete(url)
npm install axios

STANDAR URL NAMES

GET : /USERS

GET : /USERS/:id

POST : /USERS

PUT : /USERS/:id

DELETE : /USERS/:id

 

COMO TRAER DATOS. Javascript


var urlServer = 'https://jsonplaceholder.typicode.com/users';

axios.get(urlServer)

    .then( (res) => {
  		console.log('Usuarios =' ,res.data )
	}) 
    .catch( (error) => {
	  	console.log('Algo salio mal =' , error )
	})

Como usamos nuestro servicio para hacer un GET de los usuarios RESUMEN

app.component.ts

users.service.ts

Como usamos nuestro servicio para hacer un POST de un usuario nuevo

app.component.ts

users.service.ts

Vamos a crear nuestro propio backend

Para guardar los datos y modificar y leer los datos que queramos en apenas 30 segundos

Con una api restfull totalmente funcional, que permite hasta filtrado por queryparams 

(tranquilo, esto último lo entenderás más adelante)

Usando vuestra propia api

- Mete dentro de la base de datos muchas tareas con esta pinta

{ 
  "tasks" : [ 
	{ title : "tarea 1", id : 1} , 
	{ title : "tarea 2", id : 2} , 
	{ title : "tarea 3", id : 3}
	] 
} 

db.json

desde el frontend.....

Este es el front

no te olvides darle a "Fork" 

¡ Puedes usar esta base o partir del vuestro !

Usando vuestra propia api

Reutilizando la base anterior o tu propio proyecto, vamos a crear un servicio llamado TasksService para trabajar con "nuestra api".

Debemos realizar las siguientes acciones:

 

- Obtener todas las tareas.

- Añadir tarea.

- Modificar tarea.

- Borrar una tarea.

Live coding

Routing

Routing

Podemos tener una portada, una página de productos, una de contacto, etc.
Cada una de esas páginas se presenta en una url diferente del sitio web

En cualquier sitio web generalmente tienes varias direcciones o URLs

SPA - Navegando a nuevas vistas

Router 

index.html

<router-outlet>

 

 

 

 

</router-outlet>

Veamoslo con un ejemplo simple

Solo se renderiza el componente correspondiente a la ruta asignada en el routing.

¿Cómo crear un proyecto que use routing?

Paso 1. Crear un proyecto

ng new mi-proyecto

A este paso le damos YES (y)

Paso 2. revisamos el archivo app-routing

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';


const routes: Routes = [];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Paso 3. Declarar las posibles rutas.

const routes : Routes = [
    {
      path: '',
      component: GeneralComponent,
    },
    {
      path: 'Clientes',
      component: ClientesComponent,
    },
    {
      path: 'Campañas',
      component: CampanasComponent,
    },
    ...
]

En el AppRoutingModule

import {GeneralComponent} from './components/general.component';
import {ClientesComponent} from './components/general/clientes.component';
import {CampanasComponent} from './components/general/campanas.component';
import {ConfigurarComponent} from './components/general/configurar.component';

Paso 4. Cargar los "componentes/vistas" que vamos a referenciar

En el AppRoutingModule también

import {GeneralComponent} from './components/general.component';
import {ClientesComponent} from './components/general/clientes.component';
import {CampanasComponent} from './components/general/campanas.component';
import {ConfigurarComponent} from './components/general/configurar.component';

Paso 4. Poner los componentes asignados a las rutas.

const routes : Routes = [
    {
      path: '',
      component: GeneralComponent,
    },
    {
      path: 'Clientes',
      component: ClientesComponent,
    },
    {
      path: 'Campañas',
      component: CampanasComponent,
    },
    ...
]

En el AppRoutingModule

<nav class="menu">
  <button routerLink="/General">General</button>
  <button routerLink="/Clientes">Clientes</button>
  <button routerLink="/Campañas">Campañas</button>
  <button routerLink="/Configurar">Configurar</button>
</nav>

<router-outlet></router-outlet>

Paso 5. Añadimos a cada botón donde queremos que vaya.

IMPORTANTE!!!

Esto va en el app.component.html

<nav class="menu">
  <button routerLink="/General">General</button>
  <button routerLink="/Clientes">Clientes</button>
  <button routerLink="/Campañas">Campañas</button>
  <button routerLink="/Configurar">Configurar</button>
</nav>

<router-outlet></router-outlet>

Paso 5. Añadimos a cada botón donde queremos que vaya.

Es necesario poner el router-outlet. Aquí es donde se renderiza cada componente que toca para cada ruta

Inspección ! 

Inspección ! 

Inspección ! 

Inspección ! 

Mini ejercicio

Añade 3 botones más y enlaza 3 componentes nuevos, con que tengan un h2 como en el ejemplo es suficiente

Vale perfecto, eso en cuanto a páginas "genéricas", peeero ...

Es decir, con genérica o estáticas me refiero a :

1 url <=> 1componente

Pero y si quiero rehusar un componente para muuuuuuuchas URLs? 

Imagina twitter

o Youtube

o miles más, ahora verás a que me refiero

twitter.com/yuniorglez

twitter.com/antonioaren

twitter.com/nacho

Si nos damos cuenta, rehusamos el mismo componente en la misma ruta pero con datos diferentes.

Como no vamos a crear un componente por cada usuario, lo que hacemos es usar los Dynamics Links

const routes: Routes = [
  // dynamic segments start with a colon
  { path: 'user/:id', component: User}
];

user-details.component.ts

Con esto, podemos enviar información a través de la navegación, el id del usuario.
Se recoge de la siguiente forma:

constructor(private route : ActivatedRoute) {
  const id : string = this.route.snapshot.paramMap.get('id');
  //Usamos esta id para poder hacer peticiones y 
  //pedir el resto de información del usuario.
}
constructor(
  private route : ActivatedRoute,
  private usersService : UsersService
) {
  this.loadUser()
}

loadUser(){
  const id = this.route.snapshot.paramMap.get('id') as string;
  this.usersService.getUserById(id)
    .then(user => {
      this.user = user;
    })
}

user-details.component.ts

Master - Details

Master - Details

En el diseño de interfaces, la interfaz maestro - detalle, muestra una lista maestro, y una vez seleccionas uno de esto, tienes el detalle de ese item.

La mayoría de las web siguen este criterio. 

Master

Detail

Diferentes videos pero la estructura es la misma

Ejemplo Goldo

Routing

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { MasterComponent } from './components/master/master.component';
import { DetailComponent } from './components/detail/detail.component';


const routes: Routes = [
  { path: '',   redirectTo: '/todos', pathMatch: 'full' },
  {path: 'todos', component: MasterComponent },
  {path: 'todos/:id', component: DetailComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

html master

html details

<div>
  <h2>Listado de todos, Vista maestro</h2>
</div>
<div *ngFor="let todo of todos" 
  class="container-todos" 
  [routerLink]="['/todos', todo.id]">
  <div class="card mb-4" style="max-width: 100%;"  >
    <div class="column no-gutters">
      <div class="col-md-12">
        <div class="card-body">
          <h5 class="card-title">{{todo.title | titlecase}}</h5>
        </div>
      </div>
    </div>
  </div>
</div>
<div class="container card" style="width: 28rem;">
  <div class="card-body">
    <h1>Título: {{todo.title | titlecase}}</h1>
    <p *ngIf="todo.completed" class="card-text">Completado</p>
    <p *ngIf="!todo.completed" class="card-text">Sin completar</p>
  </div>
</div>

MASTER COMPONENT

import { Component } from '@angular/core';
import { Todo, TODOsService } from 'src/app/services/todos.service';

@Component({
  selector: 'master',
  templateUrl: './master.component.html',
  styleUrls: ['./master.component.css']
})
export class MasterComponent  {
  todos: Todo[] = [];

  constructor(private todoservices: TODOsService) {
    this.loadTodos()
  }

  async loadTodos(): Promise<void> {
    const allTodos = await this.todoservices.getAllTodos();

    console.log({allTodos});

    this.todos = allTodos;
  }

}

TODOS SERVICES

import { Injectable } from '@angular/core';
import axios from 'axios';

export type Todo = {
  title: string,
  id: string,
  userId: string,
  completed : boolean
}
@Injectable({
  providedIn: 'root'
})
export class TODOsService {
  APIUrl = "https://jsonplaceholder.typicode.com/todos";
  constructor() { }

  getAllTodos() : Promise<Todo[]> {
    return axios.get(this.APIUrl)
      .then( res => res.data)
  }

  getTodoById(id : string) : Promise<Todo> {
    return axios.get(`${ this.APIUrl}/${id}`)
      .then( res => res.data)
  }
}

DETAILS COMPONENT

import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { TODOsService } from 'src/app/services/todos.service';

@Component({
  selector: 'app-detail',
  templateUrl: './detail.component.html',
  styleUrls: ['./detail.component.css']
})
export class DetailComponent {
  todo: any = {};

  constructor(
    	private route: ActivatedRoute, 
    	private todosService: TODOsService) {
    this.loadTodo();
   }

  async loadTodo(): Promise<void> {
    const id = this.route.snapshot.paramMap.get('id');
    this.todo = await this.todosService.getTodoById(id);
  }

}

¿CÓMO GENERO LA RUTA?

¿CÓMO GENERO LA FAMOSA URL?

¿CÓMO GENERO LA RUTA?

¿CÓMO GENERO LA FAMOSA URL?

[routerLink]="['/todos' , todo.id]"
[routerLink]="'/todos/' + todo.id"
routerLink="/todos/{{todo.id}}"

¡Ahora a trabajar!

Ejercicio

Routing y un poco de services

Ejercicio

Routing y un poco de services

Crea una interfaz que nos permita cargar de la api de jsonplaceholder tanto usuarios como fotos como todos y como comentarios. 

 

Dibuja cada uno como veas más conveniente en la pantalla a modo de preview y ponle siempre un botón para navegar a los detalles

 

La navegación debería de llevar al usuario a una url dinámica del tipo  /details/users/:id por ejemplo donde representaremos el objeto completo en la pantalla o la mayoría de sus datos.