Commit 474c9b26 by Luciano Barletta

add type definitions in src/app/models, make Observable with cache behaviour

1 parent 27ea8d02
...@@ -7,7 +7,7 @@ import { CompraComponent } from './compra/compra.component'; ...@@ -7,7 +7,7 @@ import { CompraComponent } from './compra/compra.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', component : MainComponent }, { path: '', component : MainComponent },
{ path: 'informacion/:id', component: InformacionComponent }, { path: 'informacion/:name', component: InformacionComponent },
{ path: 'busqueda/:search', component: BusquedaComponent }, { path: 'busqueda/:search', component: BusquedaComponent },
{ path: 'comprar/:id', component: CompraComponent } { path: 'comprar/:id', component: CompraComponent }
]; ];
......
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
...@@ -25,9 +26,13 @@ import { CompraComponent } from './compra/compra.component'; ...@@ -25,9 +26,13 @@ import { CompraComponent } from './compra/compra.component';
imports: [ imports: [
BrowserModule, BrowserModule,
AppRoutingModule, AppRoutingModule,
FormsModule FormsModule,
HttpClientModule
],
providers: [
{ provide: 'confurl', useValue: "ticketech.anacsoft.com/api/configuraciones" },
ImagesService
], ],
providers: [ImagesService],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })
export class AppModule { } export class AppModule { }
<div class="EspectaculoContainer"> <div class="EspectaculoContainer">
<div class="ContainerIzquierdo"> <div class="ContainerIzquierdo">
<img class="EspectaculoImagen" src="assets/images/{{ imagename }}"> <img *ngIf="image" class="EspectaculoImagen" src="{{ image.url }}">
<div class="tab"> <div class="tab">
<svg width="70" height="75"> <svg width="70" height="75">
<a (click)="showInfo('Funciones')"> <a (click)="showInfo('Funciones')">
...@@ -52,7 +52,8 @@ ...@@ -52,7 +52,8 @@
</div> </div>
<div class="ContainerDerecho"> <div class="ContainerDerecho">
<h1>Fun Home</h1> <ng-container *ngIf="image">
<h1>{{ image.name }}</h1>
<h3>Descripcion: </h3> <h3>Descripcion: </h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
...@@ -65,8 +66,9 @@ ...@@ -65,8 +66,9 @@
ut aliquip ex ea commodo consequat.</p> ut aliquip ex ea commodo consequat.</p>
<h3>Calificacion: &#9733; &#9733; &#9733; &#9733; &#9734;</h3> <h3>Calificacion: &#9733; &#9733; &#9733; &#9733; &#9734;</h3>
<button routerLink="/comprar/{{ imageid }}" class="EspectaculoBoton" type="button"> <button routerLink="/comprar/{{ image.name }}" class="EspectaculoBoton" type="button">
Quiero mi entrada! Quiero mi entrada!
</button> </button>
</ng-container>
</div> </div>
</div> </div>
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { ImagesService } from 'src/app/services/images.service';
import { Image } from 'src/app/models/typedefs';
import { flatMap, filter } from 'rxjs/operators';
@Component({ @Component({
selector: 'app-informacion', selector: 'app-informacion',
...@@ -8,15 +12,7 @@ import { Router, ActivatedRoute } from '@angular/router'; ...@@ -8,15 +12,7 @@ import { Router, ActivatedRoute } from '@angular/router';
}) })
export class InformacionComponent implements OnInit { export class InformacionComponent implements OnInit {
private id2name = { public image : Image;
"1": "el-equilibrista.jpg",
"2": "fun-home.jpg",
"3": "giragringa.jpg",
"4": "forever-young.jpg"
};
public imagename;
public imageid;
public funciones : boolean = false; public funciones : boolean = false;
public entradas : boolean = false; public entradas : boolean = false;
...@@ -26,19 +22,27 @@ export class InformacionComponent implements OnInit { ...@@ -26,19 +22,27 @@ export class InformacionComponent implements OnInit {
constructor( constructor(
private route : ActivatedRoute, private route : ActivatedRoute,
private router : Router, private router : Router,
private images : ImagesService
) {} ) {}
ngOnInit(): void { ngOnInit(): void {
this.route.paramMap.subscribe( this.route.paramMap.pipe(
(params) => { /** foreach entry (which is only one) of paramMap **/
this.imageid = params.get('id'); flatMap(
this.imagename = this.id2name[this.imageid] /**
} * Produce a new observable of images where you filter by the name parameter
); * O(images), reduce to O(1) with a Map structure in ImagesService
*/
param => this.images.getImages().pipe(
filter( (i : Image) => i.name === decodeURIComponent(param.get('name')) )
)
)
)
/** subscribe to it and receive the image to know its values **/
.subscribe( (i : Image) => this.image = i );
} }
showInfo(show : string) { showInfo(show : string) {
console.log(show);
this.funciones = this.teatro = this.tiempo = this.entradas = false; this.funciones = this.teatro = this.tiempo = this.entradas = false;
switch (show) { switch (show) {
case "Funciones": case "Funciones":
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
<div class="mySlides" *ngFor="let i of images; let in = index"> <div class="mySlides" *ngFor="let i of images; let in = index">
<ng-container *ngIf="selected == in"> <ng-container *ngIf="selected == in">
<div class="numbertext"> {{ in + 1 }} / {{ images.length }}</div> <div class="numbertext"> {{ in + 1 }} / {{ images.length }}</div>
<button routerLink="/informacion/{{ in + 1 }}" style="padding: 0; margin: 0; border: 0;"> <button routerLink="/informacion/{{ i.name }}" style="padding: 0; margin: 0; border: 0;">
<img draggable="false" src="{{ i }}" style="width: 100%;"> <img draggable="false" src="{{ i.url }}" style="width: 100%;">
</button> </button>
</ng-container> </ng-container>
</div> </div>
...@@ -18,10 +18,10 @@ ...@@ -18,10 +18,10 @@
<!-- Thumbnail images--> <!-- Thumbnail images-->
<div class="row"> <div class="row">
<div class="column" *ngFor="let i of images; let in = index"> <div class="column" *ngFor="let i of images; let in = index">
<img draggable="false" class="demo cursor" src="{{ i }}" style="width:100%" <img draggable="false" class="demo cursor" src="{{ i.url }}" style="width:100%"
(click)="select(in)"> (click)="select(in)">
</div> </div>
</div> </div>
Novedades <h1>Novedades:</h1>
</div> </div>
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ImagesService } from 'src/app/services/images.service'; import { ImagesService } from 'src/app/services/images.service';
import { Image } from 'src/app/models/typedefs';
@Component({ @Component({
selector: 'main', selector: 'main',
templateUrl: './main.component.html', templateUrl: './main.component.html',
...@@ -8,13 +10,16 @@ import { ImagesService } from 'src/app/services/images.service'; ...@@ -8,13 +10,16 @@ import { ImagesService } from 'src/app/services/images.service';
}) })
export class MainComponent implements OnInit { export class MainComponent implements OnInit {
images : string[]; images : Image[] = [];
selected : number = 0; selected : number = 0;
constructor(private fetch : ImagesService) { } constructor(private imagesService : ImagesService) {}
ngOnInit() : void { ngOnInit() : void {
this.images = this.fetch.get(); this.imagesService.getImages()
.subscribe(
(image : Image) => this.images.push(image)
);
} }
select(s : number) : void { select(s : number) : void {
......
export interface Show {
images : Image[];
plays : Play[];
}
export interface Play {
date : string; // date class?
time : string; // time class?
description : string;
theater: Theater;
}
export interface Image {
id : number;
url : string;
name : string;
}
export interface Theater {
}
...@@ -14,8 +14,6 @@ export class NavBarComponent implements OnInit { ...@@ -14,8 +14,6 @@ export class NavBarComponent implements OnInit {
search : string = ''; search : string = '';
suggestion : boolean = false; suggestion : boolean = false;
private clearSearch$;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
...@@ -23,7 +21,7 @@ export class NavBarComponent implements OnInit { ...@@ -23,7 +21,7 @@ export class NavBarComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
/* On route change, clear search bar */ /* On route change, clear search bar */
this.clearSearch$ = this.router.events.pipe( this.router.events.pipe(
filter(event => event instanceof NavigationStart) filter(event => event instanceof NavigationStart)
) )
.subscribe( (event : NavigationStart) => { .subscribe( (event : NavigationStart) => {
......
import { Injectable, Inject, Optional } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class FetchConfigService {
constructor(
private http: HttpClient,
@Inject('confurl') private confurl : string,
@Inject('secure') @Optional() private secure? : boolean
) {
this.secure = secure ? secure : false;
this.confurl = (secure ? "https://" : "http://") + confurl;
}
public getFetchableFor(type : 'imageurls' | 'rooms' | 'events') : Observable<Object> {
return this.http.get(
`${this.confurl}/${type}`,
{ responseType : "json" }
);
}
}
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { flatMap, filter, map } from 'rxjs/operators';
import { FetchConfigService } from './fetchconfig.service';
import { Image } from 'src/app/models/typedefs';
import { assertNotNull } from '@angular/compiler/src/output/output_ast';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class ImagesService { export class ImagesService {
imageUrls : string[] = [ private idToName = new Map();
"/assets/images/el-equilibrista.jpg", private nameToId = new Map();
"/assets/images/fun-home.jpg",
"/assets/images/giragringa.jpg", private readyImages : Image[];
"/assets/images/forever-young.jpg",
]; constructor(private fetch : FetchConfigService) {}
// make observable
public getImages() : Observable<Image> {
/** if images are here, just send them **/
if (this.readyImages !== undefined)
return of(...this.readyImages);
const u = "http://ticketech.anacsoft.com/api/imagenes/";
const x = {
images: [
{ url: u + "el-equilibrista.jpg", name: "El Equilibrista", id: 1},
{ url: u + "forever-young.jpg", name: "Forever Young", id: 2},
{ url: u + "fun-home.jpg", name: "Fun Home", id: 3},
{ url: u + "giragringa.jpg", name: "Gira Gringa", id: 4},
{ url: u + "otras-canciones.jpg", name: "Otras Canciones", id: 5}
]
};
constructor() {} //return this.fetch.getFetchableFor('imageurls').pipe(
return of(x).pipe(
/** once fetched, intercept data and save it so it's not fetched again **/
map( (done) => {
this.readyImages = done['images'];
this.idToName = this.genMap("id", "name", done['images']);
this.nameToId = this.genMap("name", "id", done['images']);
console.assert(
this.readyImages === undefined,
"Data was saved locally, but it was fetched again!"
);
return done;
} ),
/** foreach data (only one in this case), serve its images **/
flatMap( (done) => of(...done['images']) )
);
}
public imageName(id : number) : string | undefined {
return this.idToName.get(id);
}
public imageId(name : string) : number | undefined {
return this.nameToId.get(name);
}
get() { /** might be slow, consider async **/
return this.imageUrls; private genMap<T, K, V>(kProp : string, vProp : string, list : T[]) : Map<K, V> {
const m = new Map;
list.forEach( (e : T) => {
m.set( e[kProp], e[vProp] );
} );
return m;
} }
} }
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!