Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ Change the value of `target` in `proxy file` as your backend api url
yarn develop
```

## Generating Environmental files in Angular 15+

```sh
ng g environments
```

## Cloning Guide

1. Clone only the remote primary HEAD (default: origin/master)
Expand Down
8 changes: 7 additions & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,13 @@
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
"sourceMap": true,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.development.ts"
}
]
}
},
"defaultConfiguration": "production"
Expand Down
12 changes: 10 additions & 2 deletions src/app/places/available-places/available-places.component.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
<app-places-container title="Available Places">
@if (isFetching() && !errorMsg()) {
<p class="fallback-text">fetching available places!</p>
}

@if (errorMsg()) {
<p class="fallback-text">{{ errorMsg() }}</p>
}

@if (places()) {
<app-places [places]="places()!" />
<app-places [places]="places()!" (selectPlace)="onSelectPlaces($event)" />
} @else if (places()?.length === 0) {
<p class="fallback-text">Unfortunately, no places could be found.</p>
<p class="fallback-text">Unfortunately, no places could be found.</p>
}
</app-places-container>
38 changes: 36 additions & 2 deletions src/app/places/available-places/available-places.component.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Component, signal } from '@angular/core';
import { Component, DestroyRef, inject, OnInit, signal } from '@angular/core';

import { Place } from '../../models/place.model';
import { PlacesComponent } from '../places.component';
import { PlacesContainerComponent } from '../places-container/places-container.component';
import { PlacesService } from '../../services/places.service';

@Component({
selector: 'app-available-places',
Expand All @@ -11,6 +12,39 @@ import { PlacesContainerComponent } from '../places-container/places-container.c
styleUrl: './available-places.component.css',
imports: [PlacesComponent, PlacesContainerComponent],
})
export class AvailablePlacesComponent {
export class AvailablePlacesComponent implements OnInit {
places = signal<Place[] | undefined>(undefined);
isFetching = signal(false);
errorMsg = signal('');

private placeServ = inject(PlacesService);
private destroyRef = inject(DestroyRef);

ngOnInit(): void {
this.isFetching.set(true);

const availablePlaceSub = this.placeServ.loadAvailablePlaces().subscribe({
next: resp => {
this.places.set(resp?.places);
this.errorMsg.set('');
},
complete: () => {
this.isFetching.set(false);
},
error: (err: Error) => {
console.error(err.message);
this.errorMsg.set(err.message);
},
});

this.destroyRef.onDestroy(() => availablePlaceSub.unsubscribe());
}

onSelectPlaces(selectedPlace: Place) {
const selectPlaceSub = this.placeServ.addPlaceToUserPlaces(selectedPlace.id).subscribe({
next: resp => console.log('Place added. ', resp),
});

this.destroyRef.onDestroy(() => selectPlaceSub.unsubscribe());
}
}
5 changes: 1 addition & 4 deletions src/app/places/places.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
@for (place of places(); track place.id) {
<li class="place-item">
<button (click)="onSelectPlace(place)">
<img
[src]="'http://localhost:3000/' + place.image.src"
[alt]="place.image.alt"
/>
<img [src]="url + place.image.src" [alt]="place.image.alt" />
<h3>{{ place.title }}</h3>
</button>
</li>
Expand Down
3 changes: 3 additions & 0 deletions src/app/places/places.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component, input, output } from '@angular/core';

import { Place } from '../models/place.model';
import { environment as env } from '../../environments/environment.development';

@Component({
selector: 'app-places',
Expand All @@ -13,6 +14,8 @@ export class PlacesComponent {
places = input.required<Place[]>();
selectPlace = output<Place>();

protected url = env.backendUrl;

onSelectPlace(place: Place) {
this.selectPlace.emit(place);
}
Expand Down
14 changes: 13 additions & 1 deletion src/app/places/user-places/user-places.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
<app-places-container title="Your Favorite Places">
<p>Todo...</p>
@if (isFetching() && !errorMsg()) {
<p class="fallback-text">fetching available places!</p>
}

@if (errorMsg()) {
<p class="fallback-text">{{ errorMsg() }}</p>
}

@if (places()) {
<app-places [places]="places()!" />
} @else if (places()?.length === 0) {
<p class="fallback-text">Unfortunately, no places could be found.</p>
}
</app-places-container>
32 changes: 30 additions & 2 deletions src/app/places/user-places/user-places.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Component } from '@angular/core';
import { Component, DestroyRef, inject, OnInit, signal } from '@angular/core';

import { PlacesContainerComponent } from '../places-container/places-container.component';
import { PlacesComponent } from '../places.component';
import { Place } from '../../models/place.model';
import { PlacesService } from '../../services/places.service';

@Component({
selector: 'app-user-places',
Expand All @@ -10,5 +12,31 @@ import { PlacesComponent } from '../places.component';
styleUrl: './user-places.component.css',
imports: [PlacesContainerComponent, PlacesComponent],
})
export class UserPlacesComponent {
export class UserPlacesComponent implements OnInit {
places = signal<Place[] | undefined>(undefined);
isFetching = signal(false);
errorMsg = signal('');

private placeServ = inject(PlacesService);
private destroyRef = inject(DestroyRef);

ngOnInit(): void {
this.isFetching.set(true);

const availablePlaceSub = this.placeServ.loadUserPlaces().subscribe({
next: resp => {
this.places.set(resp?.places);
this.errorMsg.set('');
},
complete: () => {
this.isFetching.set(false);
},
error: (err: Error) => {
console.error(err.message);
this.errorMsg.set(err.message);
},
});

this.destroyRef.onDestroy(() => availablePlaceSub.unsubscribe());
}
}
41 changes: 35 additions & 6 deletions src/app/services/places.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { Injectable, signal } from '@angular/core';
import { inject, Injectable, signal } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { catchError, map, tap } from 'rxjs/operators';
import { throwError } from 'rxjs';

import { Place } from '../models/place.model';

Expand All @@ -8,15 +12,40 @@ import { Place } from '../models/place.model';
})
export class PlacesService {
private userPlaces = signal<Place[]>([]);
private readonly url = '/api/v2/places';

loadedUserPlaces = this.userPlaces.asReadonly();

loadAvailablePlaces() {}
private http = inject(HttpClient);

loadUserPlaces() {}
loadAvailablePlaces() {
return this.fetchPlaces('/api/v2/places', 'Error loading available places!');
}

addPlaceToUserPlaces(place: Place) {}
loadUserPlaces() {
return this.fetchPlaces('/api/v2/user-places', 'Error loading user places!');
}

addPlaceToUserPlaces(placeId: string) {
return this.http.put('/api/v2/user-places', {
placeId,
});
}

removeUserPlace(place: Place) {}

private fetchPlaces(url: string, errMsg: string) {
return this.http
.get<{ places: Place[] }>(url, {
observe: 'response', // it'll give full response including status code
})
.pipe(
tap(rawResp => {
console.log('Raw Response: ', rawResp);
}),
map(data => data.body),
catchError(error => {
console.error(error);
return throwError(() => new Error(errMsg));
}),
);
}
}
3 changes: 3 additions & 0 deletions src/environments/environment.development.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const environment = {
backendUrl: 'https://3000-actionanand-angularhttp-six5y8k89a8.ws-us116.gitpod.io/',
};
3 changes: 3 additions & 0 deletions src/environments/environment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const environment = {
backendUrl: 'https://3000-actionanand-angularhttp-six5y8k89a8.ws-us116.gitpod.io/',
};