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';
const routes: Routes = [
{ path: '', component : MainComponent },
{ path: 'informacion/:id', component: InformacionComponent },
{ path: 'informacion/:name', component: InformacionComponent },
{ path: 'busqueda/:search', component: BusquedaComponent },
{ path: 'comprar/:id', component: CompraComponent }
];
......
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
......@@ -25,9 +26,13 @@ import { CompraComponent } from './compra/compra.component';
imports: [
BrowserModule,
AppRoutingModule,
FormsModule
FormsModule,
HttpClientModule
],
providers: [
{ provide: 'confurl', useValue: "ticketech.anacsoft.com/api/configuraciones" },
ImagesService
],
providers: [ImagesService],
bootstrap: [AppComponent]
})
export class AppModule { }
<div class="EspectaculoContainer">
<div class="ContainerIzquierdo">
<img class="EspectaculoImagen" src="assets/images/{{ imagename }}">
<img *ngIf="image" class="EspectaculoImagen" src="{{ image.url }}">
<div class="tab">
<svg width="70" height="75">
<a (click)="showInfo('Funciones')">
......@@ -52,7 +52,8 @@
</div>
<div class="ContainerDerecho">
<h1>Fun Home</h1>
<ng-container *ngIf="image">
<h1>{{ image.name }}</h1>
<h3>Descripcion: </h3>
<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
......@@ -65,8 +66,9 @@
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!
</button>
</ng-container>
</div>
</div>
import { Component, OnInit } from '@angular/core';
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({
selector: 'app-informacion',
......@@ -8,15 +12,7 @@ import { Router, ActivatedRoute } from '@angular/router';
})
export class InformacionComponent implements OnInit {
private id2name = {
"1": "el-equilibrista.jpg",
"2": "fun-home.jpg",
"3": "giragringa.jpg",
"4": "forever-young.jpg"
};
public imagename;
public imageid;
public image : Image;
public funciones : boolean = false;
public entradas : boolean = false;
......@@ -26,19 +22,27 @@ export class InformacionComponent implements OnInit {
constructor(
private route : ActivatedRoute,
private router : Router,
private images : ImagesService
) {}
ngOnInit(): void {
this.route.paramMap.subscribe(
(params) => {
this.imageid = params.get('id');
this.imagename = this.id2name[this.imageid]
}
);
this.route.paramMap.pipe(
/** foreach entry (which is only one) of paramMap **/
flatMap(
/**
* 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) {
console.log(show);
this.funciones = this.teatro = this.tiempo = this.entradas = false;
switch (show) {
case "Funciones":
......
......@@ -5,8 +5,8 @@
<div class="mySlides" *ngFor="let i of images; let in = index">
<ng-container *ngIf="selected == in">
<div class="numbertext"> {{ in + 1 }} / {{ images.length }}</div>
<button routerLink="/informacion/{{ in + 1 }}" style="padding: 0; margin: 0; border: 0;">
<img draggable="false" src="{{ i }}" style="width: 100%;">
<button routerLink="/informacion/{{ i.name }}" style="padding: 0; margin: 0; border: 0;">
<img draggable="false" src="{{ i.url }}" style="width: 100%;">
</button>
</ng-container>
</div>
......@@ -18,10 +18,10 @@
<!-- Thumbnail images-->
<div class="row">
<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)">
</div>
</div>
Novedades
<h1>Novedades:</h1>
</div>
import { Component, OnInit } from '@angular/core';
import { ImagesService } from 'src/app/services/images.service';
import { Image } from 'src/app/models/typedefs';
@Component({
selector: 'main',
templateUrl: './main.component.html',
......@@ -8,13 +10,16 @@ import { ImagesService } from 'src/app/services/images.service';
})
export class MainComponent implements OnInit {
images : string[];
images : Image[] = [];
selected : number = 0;
constructor(private fetch : ImagesService) { }
constructor(private imagesService : ImagesService) {}
ngOnInit() : void {
this.images = this.fetch.get();
this.imagesService.getImages()
.subscribe(
(image : Image) => this.images.push(image)
);
}
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 {
search : string = '';
suggestion : boolean = false;
private clearSearch$;
constructor(
private route: ActivatedRoute,
private router: Router,
......@@ -23,7 +21,7 @@ export class NavBarComponent implements OnInit {
ngOnInit(): void {
/* On route change, clear search bar */
this.clearSearch$ = this.router.events.pipe(
this.router.events.pipe(
filter(event => event instanceof 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 { 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({
providedIn: 'root'
})
export class ImagesService {
imageUrls : string[] = [
"/assets/images/el-equilibrista.jpg",
"/assets/images/fun-home.jpg",
"/assets/images/giragringa.jpg",
"/assets/images/forever-young.jpg",
];
private idToName = new Map();
private nameToId = new Map();
private readyImages : Image[];
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() {
return this.imageUrls;
/** might be slow, consider async **/
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!