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,21 +52,23 @@ ...@@ -52,21 +52,23 @@
</div> </div>
<div class="ContainerDerecho"> <div class="ContainerDerecho">
<h1>Fun Home</h1> <ng-container *ngIf="image">
<h3>Descripcion: </h3> <h1>{{ image.name }}</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore <h3>Descripcion: </h3>
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit
sunt in culpa qui officia deserunt mollit anim id est laborum.</p> esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident,
<h3>Elenco: </h3> sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore <h3>Elenco: </h3>
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
ut aliquip ex ea commodo consequat.</p> et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
<h3>Calificacion: &#9733; &#9733; &#9733; &#9733; &#9734;</h3> ut aliquip ex ea commodo consequat.</p>
<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,13 +21,13 @@ export class NavBarComponent implements OnInit { ...@@ -23,13 +21,13 @@ 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) => {
this.search = ''; this.search = '';
this.suggestion = false; this.suggestion = false;
} ); } );
} }
showinput() { showinput() {
......
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!