Commit d9bd9f08 authored by Jyothi Krishnu S L's avatar Jyothi Krishnu S L

Initial commit

parent 91ff577c
File added
......@@ -1549,6 +1549,22 @@
}
}
},
"@ngrx/effects": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/@ngrx/effects/-/effects-10.0.0.tgz",
"integrity": "sha512-HHcQQ6mj1Cd0rQgnX5Wp3f7G8PKhh+Rk+jofsOsE6aHQPuuNhmnDwSA1U4PT4sXNv6JmFi5GjUqBz+tuw83oFQ==",
"requires": {
"tslib": "^2.0.0"
}
},
"@ngrx/store": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/@ngrx/store/-/store-10.0.0.tgz",
"integrity": "sha512-+mhTGJXjc+55KI1pWV5SSuP+JBAr35U1AbnBYJqqXuwJVXnJ8+n6gAr06qpPN+YMf+zRQDFwAIrqyFOfMqeJHg==",
"requires": {
"tslib": "^2.0.0"
}
},
"@ngtools/webpack": {
"version": "10.0.6",
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-10.0.6.tgz",
......
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const routes: Routes = [];
const routes: Routes = [
{
path: '',
loadChildren: () => import('./modules/posts/posts.module').then(m => m.PostsModule)
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
......
This diff is collapsed.
......@@ -3,14 +3,23 @@ import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { MoviesDetailsComponent } from './modules/movies-details/movies-details.component';
import { SharedModule } from './shared/shared.module';
import { CoreModule } from './core/core.module'
import { StoreModule } from '@ngrx/store';
@NgModule({
declarations: [
AppComponent
AppComponent,
MoviesDetailsComponent
],
imports: [
BrowserModule,
AppRoutingModule
AppRoutingModule,
CoreModule,
SharedModule,
],
providers: [],
bootstrap: [AppComponent]
......
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { EffectsModule } from '@ngrx/effects'
import { StoreModule } from '@ngrx/store';
//import * as postReducer from '../modules/posts/store/posts.reducer';
import * as fromApp from '../store/app.reducer';
import { PostEffects } from '../modules/posts/store/posts.effects';
@NgModule({
declarations: [],
imports: [
CommonModule,
HttpClientModule,
StoreModule.forRoot(fromApp.appReducer),
EffectsModule.forRoot([PostEffects])
]
})
export class CoreModule { }
import { TestBed } from '@angular/core/testing';
import { ApiBaseService } from './api-base.service';
describe('ApiBaseService', () => {
let service: ApiBaseService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ApiBaseService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { Injectable } from "@angular/core";
import {
HttpClient,
HttpHeaders,
HttpParams,
} from "@angular/common/http";
import { Observable } from "rxjs";
import { environment } from "../../../environments/environment";
@Injectable({
providedIn: "root"
})
export class ApiBaseService {
baseUrl = environment.apiBaseURL;
constructor(private httpClient: HttpClient) { }
public getFullApiRoute(route: string, id?: number): string {
let apiRoute;
if (id) {
apiRoute = `${this.baseUrl}/${route}/${id}`;
} else {
apiRoute = `${this.baseUrl}/${route}/`;
}
return apiRoute;
}
private getDefaultHeaders() {
let headers = new HttpHeaders();
headers = headers
.append("Content-Type", "application/json")
.append("Access-Control-Allow-Methods", "*")
.append("Access-Control-Allow-Methods", "GET,POST,OPTIONS,DELETE,PUT")
.append("Access-Control-Allow-Origin", "*")
return headers;
}
private getHttpParams(params?) {
return new HttpParams({
fromObject: params
});
}
private getOptions(optionalParams?) {
const headers = this.getDefaultHeaders();
const httpParams = this.getHttpParams(optionalParams);
return { params: httpParams, headers: headers };
}
/**
* GET
*/
public get<T>(route: string, params?): Observable<T> {
return this.httpClient.get<T>(
this.getFullApiRoute(route),
this.getOptions(params)
);
}
public getById<T>(route: string, id: number, params?): Observable<T> {
return this.httpClient.get<T>(
this.getFullApiRoute(route, id),
this.getOptions(params)
);
}
/**
* POST
*/
public post<T>(route: string, data?, params?): Observable<T> {
return this.httpClient.post<T>(
this.getFullApiRoute(route),
JSON.stringify(data),
this.getOptions(params)
);
}
public postById<T>(route: string, id: number, data?, params?): Observable<T> {
return this.httpClient.post<T>(
this.getFullApiRoute(route, id),
data,
this.getOptions(params)
);
}
/**
* PUT
*/
public put(route: string, data, params?) {
return this.httpClient.put(
this.getFullApiRoute(route),
JSON.stringify(data),
this.getOptions(params)
);
}
public putById(route: string, id: number, data?, params?) {
return this.httpClient.put(
this.getFullApiRoute(route, id),
data,
this.getOptions(params)
);
}
/**
* DELETE
*/
public delete(route: string, params?) {
return this.httpClient.delete(
this.getFullApiRoute(route),
this.getOptions(params)
);
}
public deleteById(route: string, id: number, params?) {
return this.httpClient.delete(
this.getFullApiRoute(route, id),
this.getOptions(params)
);
}
}
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ListMoviesComponent } from './list-movies.component';
describe('ListMoviesComponent', () => {
let component: ListMoviesComponent;
let fixture: ComponentFixture<ListMoviesComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ListMoviesComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ListMoviesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-list-movies',
templateUrl: './list-movies.component.html',
styleUrls: ['./list-movies.component.scss']
})
export class ListMoviesComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ListMoviesComponent } from './list-movies.component';
@NgModule({
declarations: [ListMoviesComponent],
imports: [
CommonModule
]
})
export class ListMoviesModule { }
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MoviesDetailsComponent } from './movies-details.component';
describe('MoviesDetailsComponent', () => {
let component: MoviesDetailsComponent;
let fixture: ComponentFixture<MoviesDetailsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MoviesDetailsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MoviesDetailsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-movies-details',
templateUrl: './movies-details.component.html',
styleUrls: ['./movies-details.component.scss']
})
export class MoviesDetailsComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@NgModule({
declarations: [],
imports: [
CommonModule
]
})
export class MoviesDetailsModule { }
<p *ngIf=" (selectedPost | async).selectedIndex >= 0 ">
{{ (selectedPost | async ).selectedPost.body }}
</p>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { PostListItemDetailComponent } from './post-list-item-detail.component';
describe('PostListItemDetailComponent', () => {
let component: PostListItemDetailComponent;
let fixture: ComponentFixture<PostListItemDetailComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PostListItemDetailComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PostListItemDetailComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import * as fromApp from '../../../../store/app.reducer'
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { Posts } from 'src/app/shared/models/posts.model';
@Component({
selector: 'app-post-list-item-detail',
templateUrl: './post-list-item-detail.component.html',
styleUrls: ['./post-list-item-detail.component.scss']
})
export class PostListItemDetailComponent implements OnInit {
selectedPost: Observable<{
selectedIndex: number,
selectedPost: Posts
}>
constructor(
private store: Store<fromApp.AppState>
) { }
ngOnInit(): void {
this.selectedPost = this.store.select('post')
}
}
<div class="list-wrap" (click)="selectItem(post.id
)" >
<div>
<h3>
{{ post.title }}
</h3>
</div>
<div>
<p>
{{ post.body }}
</p>
</div>
</div>
.list-wrap{
border: 1px solid #ddd;
border-radius: 15px;
padding: 15px;
margin-bottom: 15px;
cursor: pointer;
}
.list-wrap:hover{
background: #ddd;
color: black;
}
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { PostListItemComponent } from './post-list-item.component';
describe('PostListItemComponent', () => {
let component: PostListItemComponent;
let fixture: ComponentFixture<PostListItemComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PostListItemComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PostListItemComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Input, OnChanges } from '@angular/core';
import { Posts } from 'src/app/shared/models/posts.model';
import * as fromApp from '../../../../store/app.reducer';
import * as PostActions from '../../store/posts.action';
import { Store } from '@ngrx/store';
@Component({
selector: 'app-post-list-item',
templateUrl: './post-list-item.component.html',
styleUrls: ['./post-list-item.component.scss']
})
export class PostListItemComponent implements OnInit, OnChanges {
@Input() post: Posts;
constructor(
private store: Store<fromApp.AppState>
) { }
ngOnChanges(): void{
// console.log("Post ---", this.post);
}
ngOnInit(): void {
}
selectItem(id: number){
this.store.dispatch(new PostActions.SelectPost(id))
}
}
<div class="post-wrap" >
<div class="post-content content-left" >
<div class="post-list" *ngFor="let post of posts" >
<app-post-list-item [post]="post"></app-post-list-item>
</div>
</div>
<div class="post-content content-right" >
<div class="right-sec-wrap" >
<p>Selected Post</p>
<app-post-list-item-detail></app-post-list-item-detail>
</div>
</div>
</div>
.post-wrap{
display: flex;
width: 100%;
.post-content{
flex: 1;
}
.right-sec-wrap{
padding: 15px;
p{
font-size: 20px;
position: relative;
&:after{
content: "";
position: absolute;
width: 40%;
background: #139a13;
padding: 5px;
top: 22px;
left:0;
border-radius: 15px;
}
}
}
}
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { PostListComponent } from './post-list.component';
describe('PostListComponent', () => {
let component: PostListComponent;
let fixture: ComponentFixture<PostListComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PostListComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PostListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import { PostsService } from '../../services/posts.service';
import { Posts } from 'src/app/shared/models/posts.model';
import { Store } from '@ngrx/store'
import * as fromApp from '../../../../store/app.reducer'
@Component({
selector: 'app-post-list',
templateUrl: './post-list.component.html',
styleUrls: ['./post-list.component.scss']
})
export class PostListComponent implements OnInit {
posts: Array<Posts>;
constructor(
private postsService: PostsService,
private store: Store<fromApp.AppState>
) { }
ngOnInit(): void {
this.store.select('post').subscribe(data => {
this.posts = [...data.posts]
})
}
}
import { NgModule } from "@angular/core";
import { Routes, RouterModule } from '@angular/router';
import { PostListComponent } from './components/post-list/post-list.component';
import { PostListItemDetailComponent } from './components/post-list-item-detail/post-list-item-detail.component';
import { PostResolverService } from './services/post-resolver.service'
const routes: Routes = [
{
path: '',
component: PostListComponent,
resolve: [PostResolverService]
},
{
path: ':/id',
component: PostListItemDetailComponent
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: []
})
export class PostsRoutingModule{}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { PostsRoutingModule } from './posts-routing.module';
import { PostListComponent } from './components/post-list/post-list.component';
import { PostListItemComponent } from './components/post-list-item/post-list-item.component';
import { PostListItemDetailComponent } from './components/post-list-item-detail/post-list-item-detail.component'
@NgModule({
declarations: [PostListComponent, PostListItemComponent, PostListItemDetailComponent],
imports: [
CommonModule,
PostsRoutingModule
]
})
export class PostsModule { }
import { TestBed } from '@angular/core/testing';
import { PostResolverService } from './post-resolver.service';
describe('PostResolverService', () => {
let service: PostResolverService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(PostResolverService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { Store } from '@ngrx/store';
import { Actions, ofType } from '@ngrx/effects'
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRoute, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { PostsService } from './posts.service';
import * as fromApp from '../../../store/app.reducer';
import * as RecipieActions from '../store/posts.action'
import { take } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class PostResolverService implements Resolve<any>{
constructor(
private postsService: PostsService,
private actions$: Actions,
private store: Store<fromApp.AppState>) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot){
// this.postsService.getAllPosts().subscribe();
this.store.dispatch(new RecipieActions.GetPost());
return this.actions$.pipe(
ofType(RecipieActions.SET_POST),
take(1)
)
}
}
import { TestBed } from '@angular/core/testing';
import { PostsService } from './posts.service';
describe('PostsService', () => {
let service: PostsService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(PostsService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { Injectable } from '@angular/core';
import { ApiBaseService } from '../../../core/services/api-base.service';
import { tap } from 'rxjs/operators'
import { Store } from '@ngrx/store';
import * as postReducer from '../store/posts.reducer';
import { Posts } from '../../../shared/models/posts.model'
import * as Postactions from '../store/posts.action';
@Injectable({
providedIn: 'root'
})
export class PostsService {
private readonly url: string = 'posts';
constructor(
private http: ApiBaseService,
private store: Store<postReducer.State>
) { }
getAllPosts(){
return this.http.get<Array<Posts>>(this.url).pipe(
tap(data => {
this.store.dispatch(
new Postactions.SetPost(data)
)
})
)
}
}
import { Action } from '@ngrx/store';
import { Posts } from '../../../shared/models/posts.model';
export const GET_POST = '[Post] Get Post';
export const SELECT_POST = '[Post] Select Post';
export const SET_POST = '[Post] Set Post';
export class GetPost implements Action{
readonly type = GET_POST;
}
export class SelectPost implements Action{
readonly type = SELECT_POST;
constructor(public id: number){}
}
export class SetPost implements Action{
readonly type = SET_POST;
constructor(public payload: Array<Posts>){}
}
export type PostActions = | GetPost | SelectPost | SetPost;
import { Injectable } from '@angular/core'
import { Effect, Actions, ofType } from '@ngrx/effects';
import { map, switchMap, tap } from 'rxjs/operators';
import * as PostActions from '../../posts/store/posts.action'
import { ApiBaseService } from '../../../core/services/api-base.service';
import { Posts } from 'src/app/shared/models/posts.model';
@Injectable()
export class PostEffects {
private readonly url: string = 'posts';
constructor(
private actions$: Actions,
private apiService: ApiBaseService
){}
@Effect()
fetchPost = this.actions$.pipe(
ofType(PostActions.GET_POST),
switchMap(() => {
return this.apiService.get<Array<Posts>>(this.url)
}),
map(posts => {
return new PostActions.SetPost(posts)
})
)
}
import { Posts } from '../../../shared/models/posts.model';
import * as PostAction from './posts.action';
export interface State{
posts: Array<Posts>,
selectedIndex: number,
selectedPost: Posts
}
const initialState: State = {
posts: [],
selectedIndex: -1,
selectedPost: null
}
export function postReducer(
state = initialState,
action: PostAction.PostActions
){
switch(action.type){
case PostAction.SET_POST:
return{
...state,
posts: [...action.payload],
}
case PostAction.SELECT_POST:
const post = state.posts.filter(el => el.id == action.id)
return{
...state,
posts:[...state.posts],
selectedIndex: post[0].id,
selectedPost: post[0]
}
default:
return state;
}
}
export interface Posts {
userId: number,
id: number,
title: string,
body: string,
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@NgModule({
declarations: [],
imports: [
CommonModule
]
})
export class MaterialModule { }
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms'
import { MaterialModule } from './modules/material/material.module'
@NgModule({
declarations: [],
imports: [
CommonModule,
FormsModule,
MaterialModule
]
})
export class SharedModule { }
import { ActionReducerMap } from '@ngrx/store';
import * as fromPost from '../modules/posts/store/posts.reducer';
export interface AppState{
post: fromPost.State
}
export const appReducer: ActionReducerMap<AppState> = {
post: fromPost.postReducer
}
......@@ -3,7 +3,8 @@
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false
production: false,
apiBaseURL: 'https://jsonplaceholder.typicode.com'
};
/*
......
/* You can add global styles to this file, and also import other style files */
body{
padding: 15px;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment