Skip to content

Commit

Permalink
category_id implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
puzansakya committed Feb 21, 2019
1 parent 1ed1868 commit 75958d0
Show file tree
Hide file tree
Showing 17 changed files with 353 additions and 218 deletions.
2 changes: 1 addition & 1 deletion server/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class App {

constructor() {
// change the database environment here
Model.knex(Knex(objection.production));
Model.knex(Knex(objection.development));

this.httpFlush = new HttpFlush();
this.express = express();
Expand Down
3 changes: 2 additions & 1 deletion server/src/controller/Article.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ export class ArticleController {
content: req.body.content,
backdrop: result.secure_url,
status: req.body.status,
user_id: user.sub
user_id: user.sub,
category_id: req.body.category_id,
}).debug(true);
res.status(201).json(articleCreate);
} catch (error) {
Expand Down
1 change: 1 addition & 0 deletions server/src/models/Article.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default class Article extends Model {
modified_date: Date;
status: boolean;
user_id: number;
category_id: number;

static get tableName() {
return 'articles';
Expand Down
5 changes: 5 additions & 0 deletions server/src/swagger/Article.swagger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@
* description: Article's heading
* required: true
* type: string
* - name: category_id
* in: formData
* description: Category's id
* required: true
* type: number
* - name: slug
* in: formData
* description: Article's slug
Expand Down
189 changes: 166 additions & 23 deletions src/app/article/guards/article.guard.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,76 @@
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot } from '@angular/router';
import { Injectable, OnInit } from '@angular/core';
import {
CanActivate,
ActivatedRouteSnapshot
} from '@angular/router';

import { Store } from '@ngrx/store';
import { of, Observable, combineLatest } from 'rxjs';
import { map, flatMap } from 'rxjs/operators';
import {
flatMap,
map,
tap,
switchMap,
catchError,
take,
filter,
first,
takeLast,
concat,
delay
} from 'rxjs/operators';
import {
of,
Observable,
combineLatest
} from 'rxjs';

// store imports
import * as fromArticleStore from '../../root-store/article-store';
import * as fromAuthStore from '../../root-store/auth-store';
import { SeoService } from '../../core/services';
import { Article } from '../../core/models/article.model';
import { User } from '../../core/models/user.model';

@Injectable()
export class ArticleGuard implements CanActivate {

values$ = combineLatest(
this.articleStore.select(fromArticleStore.getArticle),
this.authStore.select(fromAuthStore.getAuthUser)
).pipe(
map(([first, second]) => {
// combineLatest returns an array of values, here we map those values to an object
return { first, second };
})
);

constructor(
private articleStore: Store<fromArticleStore.ArticleState>,
private authStore: Store<fromAuthStore.AuthState>
) {
private authStore: Store<fromAuthStore.AuthState>,
private seo: SeoService
) { }

}
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
// this.checkStore()
// .subscribe(x => console.log('PROF X', x));
// this.articleStore.dispatch(new fromArticleStore.LoadArticle(route.params.slug));
// this.checkTest(route.params.slug);
let slug = route.params.slug;
this.checkTest(slug);
return this.checkArticle(slug).pipe(
switchMap(() => of(true)),
catchError(() => of(false))
);
// return of(true);
// let articleSlug;
// let slug = route.params.slug;
// this.articleStore.select(fromArticleStore.getArticle).pipe(
// take(1)
// ).subscribe((article: Article) => {
// console.log(article.slug);
// articleSlug = article.slug;
// });

canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
this.checkStore()
.subscribe(x => console.log('PROF X', x));
this.articleStore.dispatch(new fromArticleStore.LoadArticle(route.params.slug));
return of(true);
// if (articleSlug !== slug) {
// this.articleStore.dispatch(new fromArticleStore.LoadArticle(slug));
// }
// return of(true);
}

/**
*
* Checks if the authenticated user id and article's author id matches
*
* @returns {Observable<boolean>}
*/
checkStore(): Observable<boolean> {

Expand All @@ -47,8 +81,117 @@ export class ArticleGuard implements CanActivate {
this.authStore.select(fromAuthStore.getAuthUser)
).pipe(
flatMap(([first, second]) => {
// checking user id with author id
// combineLatest returns an array of values, here we map those values to an object
return first && first.user.id === second.id ? of(true) : of(false);
})
);
}

/**
*
* @param slug check
*/
checkArticle(slug: string): Observable<boolean> {
return this.articleStore.select(fromArticleStore.getArticle).pipe(
tap(article => {
if (article === null || article.slug !== slug) {
this.articleStore.dispatch(new fromArticleStore.LoadArticle(slug))
}
}),
map((article: Article) => !!article),
take(1)
)
// .subscribe();
}

checkUser(slug: string): Observable<boolean> {
return this.articleStore.select(fromArticleStore.getArticle).pipe(
take(1),
map(article => article),
switchMap(article => {
return this.authStore.select(fromAuthStore.getAuthUser)
.pipe(
take(1),
map(user => user),
switchMap(user => {
return user.id === article.user.id ? of(true) : of(false);
})
)
}))
}

checkTest(slugger: string) {

interface IUser {
id?: number,
username?: string,
}
interface IArticle {
id?: number,
title?: string,
user_id?: number,
slug?: string
}
const user: IUser = {
id: 1,
username: 'puzansakya',
}
const article: IArticle = {
id: 1,
title: 'Article title 1',
slug: 'article1',
user_id: 3
}
const articleStore: IArticle = {
id: 1,
title: 'Article title 1',
slug: 'how-to-improve-your-javascript-skills-by-writing-your-own-web-development-framework',
user_id: 3
}

const userObservable = of(user).pipe(delay(2000));
const articleObservable = of(article);
const articleStoreObservable = of(articleStore);

const checkUserObservable = articleObservable.pipe(
take(1),
map(article => article),
switchMap(article => {
return userObservable
.pipe(
take(1),
map(user => user),
switchMap(user => {
return user.id === article.user_id ? of(true) : of(false);
})
)
})
)

const checkSlugObservable = this.articleStore.select(fromArticleStore.getArticle).pipe(
take(1),
map(articleStore => articleStore),
tap(articleStore => {
console.log('debug1');
if (slugger !== articleStore.slug) {
console.log('debug2');
this.articleStore.dispatch(new fromArticleStore.LoadArticle(slugger))
}
}),
map(articleStore => !!articleStore)
)

of('Start').pipe(
concat(
of('', '===============', 'Start checkuser:', '===============', ''),
checkUserObservable,
of('', '===============', 'End checkuser:', '===============', ''),
of('', '===============', 'Start checkSlug:', '===============', ''),
checkSlugObservable,
of('', '===============', 'End checkSlug:', '===============', ''),
)
).subscribe(x => console.log(x));

}
}
21 changes: 11 additions & 10 deletions src/app/core/models/article.model.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { User } from "./user.model";

export interface Article {
id? : number;
heading? : string;
slug? : string;
content? : string;
description?: string;
backdrop? : string;
status? : string;
created_at? : string;
bookmark? : boolean;
id? : number;
heading? : string;
slug? : string;
content? : string;
description? : string;
backdrop? : string;
status? : string;
created_at? : string;
bookmark? : boolean;
// category? : string;
// author?: string;
// avatar?: string;
user? : User;
user? : User;
category_id? : number;
}
6 changes: 3 additions & 3 deletions src/app/core/services/article.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ export class ArticleService {

getArticles(page: number): Observable<Articles> {
return this.http
.get<Articles>(`https://medium-puzan.herokuapp.com/api/v1/articles?page=${page}&limit=12&sort=id&order=desc`)
.get<Articles>(`http://localhost:3000/api/v1/articles?page=${page}&limit=12&sort=id&order=desc`)
.pipe(catchError((error: any) => Observable.throw(error.json())));
}

getArticle(slug: string): Observable<Article> {
return this.http
.get<Article>(`https://medium-puzan.herokuapp.com/api/v1/articles/${slug}`)
.get<Article>(`http://localhost:3000/api/v1/articles/${slug}`)
.pipe(catchError((error: any) => Observable.throw(error.json())));
}

Expand All @@ -37,7 +37,7 @@ export class ArticleService {
formdata.append('content', payload.article.content);

return this.http
.post<Article>(`https://medium-puzan.herokuapp.com/api/v1/articles`, formdata)
.post<Article>(`http://localhost:3000/api/v1/articles`, formdata)
.pipe(catchError((error: any) => Observable.throw(error.json())));
}
}
2 changes: 1 addition & 1 deletion src/app/core/services/authentication.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class AuthenticationService {
}

login(email: string, password: string) {
return this.http.post<any>(`https://medium-puzan.herokuapp.com/api/v1/user/login`, { email, password })
return this.http.post<any>(`http://localhost:3000/api/v1/user/login`, { email, password })
.pipe(map(user => {
// login successful if there's a jwt token in the response
if (user && user.token) {
Expand Down
6 changes: 3 additions & 3 deletions src/app/core/services/category.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ export class CategoryService {

getCategory(): Observable<ResponseWrapper<Category>> {
return this.http
.get<ResponseWrapper<Category>>(`https://medium-puzan.herokuapp.com/api/v1/categories?limit=30`)
.get<ResponseWrapper<Category>>(`http://localhost:3000/api/v1/categories?limit=30`)
.pipe(catchError((error: any) => Observable.throw(error.json())));
}

createCategory(payload: Category): Observable<Category> {
return this.http
.post<Category>(`https://medium-puzan.herokuapp.com/api/v1/categories`, payload)
.post<Category>(`http://localhost:3000/api/v1/categories`, payload)
.pipe(catchError((error: any) => Observable.throw(error.json())));
}

updateCategory(payload: Category): Observable<Category> {
return this.http
.put<Category>(`https://medium-puzan.herokuapp.com/api/v1/categories/${payload.id}`, payload)
.put<Category>(`http://localhost:3000/api/v1/categories/${payload.id}`, payload)
.pipe(catchError((error: any) => Observable.throw(error.json())));
}
}
13 changes: 8 additions & 5 deletions src/app/core/services/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { ArticleService } from './article.service';
import { CategoryService } from './category.service';
import { AuthenticationService } from './authentication.service';
import { ArticleService } from './article.service';
import { CategoryService } from './category.service';
import { AuthenticationService } from './authentication.service';
import { SeoService } from './seo.service';

export const services: any[] = [
ArticleService,
AuthenticationService,
CategoryService
CategoryService,
SeoService
]

export * from './article.service';
export * from './category.service';
export * from './authentication.service';
export * from './authentication.service';
export * from './seo.service';
Loading

0 comments on commit 75958d0

Please sign in to comment.