├── .gitignore
├── LICENSE.md
├── README.md
├── bs-config.json
├── db.json
├── demo.gif
├── gulpfile.js
├── index.html
├── package.json
├── src
├── html
│ ├── app.html
│ ├── dashboard
│ │ └── dashboard.html
│ └── post
│ │ └── post.html
├── scss
│ ├── _dashboard.scss
│ ├── _post.scss
│ └── app.scss
└── ts
│ ├── app.component.ts
│ ├── app.module.ts
│ ├── dashboard
│ └── components
│ │ └── dashboard.component.ts
│ ├── main.ts
│ ├── post
│ ├── components
│ │ └── post.component.ts
│ ├── models
│ │ └── comment.ts
│ └── services
│ │ └── comment.service.ts
│ ├── rxjs-extensions.ts
│ └── shared
│ ├── models
│ └── post.ts
│ └── services
│ ├── logging.service.ts
│ └── post.service.ts
├── system-config.js
├── tsconfig.json
└── tslint.json
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .idea/
3 | node_modules
4 | app
5 | npm-debug.log
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Maximilian Schwarzmüller
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Angular 2 BeyondScheme Discussion Portal
2 |
3 | ## Description
4 | This project is a discussion portal written in Angular 2 which periodically pulls data from backend to keep fresh data on UI without refreshing the page.
5 |
6 | It is derived from the official Angular 2 Documentation which can be found [here](https://angular.io/docs/ts/latest/tutorial/).
7 |
8 | Quick demo:
9 |
10 |
11 |
12 | ## Usage
13 | Follow the following steps.
14 |
15 | 0: Install npm, typescript and json server
16 | ```
17 | npm install -g json-server
18 | ```
19 | ```
20 | npm install -g typescript
21 | ```
22 | 1: Clone repo
23 | ```
24 | git clone
25 | ```
26 | 2: Install packages
27 | ```
28 | npm install
29 | ```
30 | 3: Start server (includes auto refreshing) and gulp watcher
31 | ```
32 | npm start
33 | ```
34 |
35 | # Port bindings
36 | Json-server is bind to port 3000, lite server to port 8000 (application is visible at this port) and BrowserSync (used by lite server) to port 8001.
37 | You can change lite server and BrowserSync ports in `bs-config.json`. Json-server port can be changed in `package.json` file by changing:
38 |
39 | `"start": "concurrent \"json-server --watch db.json\" \"npm run gulp\" \"npm run lite\" "` to:
40 |
41 | `"start": "concurrent \"json-server --watch db.json --port NEW_PORT\" \"npm run gulp\" \"npm run lite\" "`
42 |
43 | Please remember that when you change json-server port you have to fix urls in files:
44 |
45 | * [`comment.service.ts`](https://github.com/BeyondScheme/angular2-discussion-portal/blob/master/src/ts/post/services/comment.service.ts)
46 | * [`post.service.ts`](https://github.com/BeyondScheme/angular2-discussion-portal/blob/master/src/ts/shared/services/post.service.ts)
47 |
48 | # About Beyond Scheme
49 |
50 | Angular 2 discussion portal is maintained by [BeyondScheme.com](http://beyondscheme.com/?utm_source=github)
51 |
52 | Yet another software engineers, are we?
53 | We build web applications on a daily basis.
54 |
55 | See [what we do or hire us](http://beyondscheme.com/?utm_source=github) to help you with your product.
--------------------------------------------------------------------------------
/bs-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "ghostMode": false,
3 | "port": 8000,
4 | "ui": {
5 | "port": 8001
6 | }
7 | }
--------------------------------------------------------------------------------
/db.json:
--------------------------------------------------------------------------------
1 | {
2 | "posts": [
3 | {
4 | "title": "angular2 released!",
5 | "id": 2
6 | }
7 | ],
8 | "comments": []
9 | }
--------------------------------------------------------------------------------
/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BeyondScheme/angular2-discussion-portal/e1532051998c5088b29e72f8969ba38f6f2fae9c/demo.gif
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var $ = require('gulp-load-plugins')({lazy: true});
3 | var sass = require('gulp-sass');
4 |
5 | var paths = {
6 | src: {
7 | ts: './src/ts/**/*.ts',
8 | scss: './src/scss/app.scss'
9 | },
10 | dest: {
11 | js: './app/js',
12 | css: './app/css'
13 | }
14 | };
15 |
16 | gulp.task("tslint", function () {
17 | gulp.src([paths.src.ts])
18 | .pipe($.tslint({
19 | formatter: "verbose"
20 | }))
21 | .pipe($.tslint.report());
22 | });
23 |
24 | gulp.task('build-ts', ["tslint", "build-scss"], function () {
25 | return gulp.src(paths.src.ts)
26 | .pipe($.sourcemaps.init())
27 | .pipe($.typescript.createProject('tsconfig.json', {
28 | typescript: require('typescript')
29 | })())
30 | .pipe($.sourcemaps.write())
31 | .pipe($.inlineNg2Template())
32 | .pipe(gulp.dest(paths.dest.js));
33 | });
34 |
35 | gulp.task('build-scss', function () {
36 | return gulp.src(paths.src.scss)
37 | .pipe(sass().on('error', sass.logError))
38 | .pipe(gulp.dest(paths.dest.css));
39 | });
40 |
41 | gulp.task('watch', function () {
42 | gulp.watch(paths.src.ts, ['build-ts']);
43 | gulp.watch(paths.src.scss, ['build-scss']);
44 | });
45 |
46 | gulp.task('default', ['watch', 'build-ts', 'build-scss']);
47 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Angular BeyondScheme
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
21 |
22 |
23 |
24 | Loading...
25 |
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular2-BeyondScheme",
3 | "version": "1.0.0",
4 | "scripts": {
5 | "lite": "lite-server",
6 | "gulp": "gulp",
7 | "json-server": "json-server",
8 | "start": "concurrent \"json-server --watch db.json\" \"npm run gulp\" \"npm run lite\" "
9 | },
10 | "license": "ISC",
11 | "dependencies": {
12 | "@angular/common": "~2.2.0",
13 | "@angular/compiler": "~2.2.0",
14 | "@angular/core": "~2.2.0",
15 | "@angular/forms": "~2.2.0",
16 | "@angular/http": "~2.2.0",
17 | "@angular/platform-browser": "~2.2.0",
18 | "@angular/platform-browser-dynamic": "~2.2.0",
19 | "@angular/router": "~3.2.0",
20 | "@angular/upgrade": "~2.2.0",
21 |
22 | "systemjs": "0.19.39",
23 | "core-js": "^2.4.1",
24 | "reflect-metadata": "^0.1.8",
25 | "rxjs": "5.0.0-beta.12",
26 | "zone.js": "^0.6.25"
27 | },
28 | "devDependencies": {
29 | "concurrently": "^2.0.0",
30 | "gulp": "^3.9.0",
31 | "gulp-inline-ng2-template": "^4.0.0",
32 | "gulp-load-plugins": "1.4.0",
33 | "gulp-sourcemaps": "^2.2.0",
34 | "gulp-sass": "2.3.2",
35 | "gulp-tslint": "6.1.2",
36 | "gulp-typescript": "^3.1.3",
37 | "lite-server": "^2.1.0",
38 | "tslint": "^3.7.3",
39 | "typescript": "^2.0.10",
40 |
41 | "@types/core-js": "^0.9.34",
42 | "@types/node": "^6.0.46"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/html/app.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/html/dashboard/dashboard.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Posts
7 |
8 |
9 |
10 |
{{post.title}}
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/html/post/post.html:
--------------------------------------------------------------------------------
1 |
2 |
{{post.title}}
3 |
4 |
5 |
6 |
7 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/scss/_dashboard.scss:
--------------------------------------------------------------------------------
1 | *, *:after, *:before {
2 | -webkit-box-sizing: border-box;
3 | -moz-box-sizing: border-box;
4 | box-sizing: border-box;
5 | }
6 |
7 | [class*='col-'] {
8 | float: left;
9 | padding-right: 20px;
10 | padding-bottom: 20px;
11 | }
12 |
13 | [class*='col-']:last-of-type {
14 | padding-right: 0;
15 | }
16 |
17 | .grid {
18 | margin: 0;
19 | display: inline-block;
20 | }
21 |
22 | .module {
23 | position: relative;
24 | padding: 20px;
25 | text-align: center;
26 | color: #eee;
27 | max-height: 120px;
28 | min-width: 120px;
29 | background-color: #607D8B;
30 | background-color: rgb(0, 120, 215);
31 | border-radius: 2px;
32 | }
33 |
34 | .module:hover {
35 | background-color: #EEE;
36 | background-color: #CCC;
37 | cursor: pointer;
38 | color: #607d8b;
39 | }
40 |
41 | #add-new-post {
42 | margin-top: 20px;
43 | }
44 |
45 | #add-new-post input {
46 | width: 400px;
47 | }
48 |
49 | button.delete-button {
50 | position: absolute;
51 | top: 0;
52 | right: 0;
53 | background-color: gray !important;
54 | color: white;
55 | }
--------------------------------------------------------------------------------
/src/scss/_post.scss:
--------------------------------------------------------------------------------
1 | #add-button {
2 | vertical-align: text-bottom;
3 | }
4 |
5 | .comments {
6 | list-style-type: none;
7 | padding: 0;
8 | }
9 |
10 | .comments li {
11 | position: relative;
12 | left: 0;
13 | background-color: #e4f0f3;
14 | margin: .5em .5em .5em 0;
15 | padding: .3em 0;
16 | height: 1.6em;
17 | border-radius: 4px;
18 | }
19 |
20 | .comments .text {
21 | position: relative;
22 | top: -3px;
23 | }
24 |
25 | button.delete-button{
26 | float:right;
27 | background-color: gray !important;
28 | background-color: rgb(216,59,1) !important;
29 | color:white;
30 | }
31 |
--------------------------------------------------------------------------------
/src/scss/app.scss:
--------------------------------------------------------------------------------
1 | @import "_dashboard.scss";
2 | @import "_post.scss";
3 |
4 | body {
5 | margin: 32px;
6 | font-family: "Roboto", Arial, sans-serif;
7 | }
8 | nav a {
9 | padding: 5px 10px;
10 | text-decoration: none;
11 | margin-top: 10px;
12 | display: inline-block;
13 | background-color: #eee;
14 | border-radius: 5px;
15 | }
16 |
17 | nav a:visited, a:link {
18 | color: #607D8B;
19 | }
20 |
21 | nav a:hover {
22 | color: #039be5;
23 | background-color: #CFD8DC;
24 | }
25 |
26 | nav a.active {
27 | color: #039be5;
28 | }
29 |
30 | button {
31 | font-family: Arial;
32 | background-color: #eee;
33 | border: none;
34 | padding: 5px 10px;
35 | border-radius: 4px;
36 | cursor: pointer;
37 | cursor: hand;
38 | }
39 |
40 | button:hover {
41 | background-color: #cfd8dc;
42 | }
--------------------------------------------------------------------------------
/src/ts/app.component.ts:
--------------------------------------------------------------------------------
1 | import {Component} from "@angular/core";
2 |
3 | @Component({
4 | selector: "my-app",
5 | templateUrl: "/src/html/app.html",
6 | })
7 | export class AppComponent {
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/src/ts/app.module.ts:
--------------------------------------------------------------------------------
1 | import {AppComponent} from "./app.component";
2 | import {DashboardComponent} from "./dashboard/components/dashboard.component";
3 | import {PostComponent} from "./post/components/post.component";
4 | import "./rxjs-extensions";
5 | import {LoggingService} from "./shared/services/logging.service";
6 | import {PostService} from "./shared/services/post.service";
7 | import {NgModule} from "@angular/core";
8 | import {FormsModule} from "@angular/forms";
9 | import {HttpModule} from "@angular/http";
10 | import {BrowserModule} from "@angular/platform-browser";
11 | import {RouterModule, Routes} from "@angular/router";
12 |
13 | const routes: Routes = [
14 | {
15 | path: "",
16 | pathMatch: "full",
17 | redirectTo: "/dashboard",
18 | },
19 | {
20 | component: DashboardComponent,
21 | path: "dashboard",
22 | },
23 | {
24 | component: PostComponent,
25 | path: "post/:id",
26 | },
27 | ];
28 | export const routedComponents = [DashboardComponent, PostComponent];
29 |
30 | @NgModule({
31 | bootstrap: [AppComponent],
32 | declarations: [AppComponent, routedComponents],
33 | imports: [BrowserModule, FormsModule, HttpModule, RouterModule.forRoot(routes)],
34 | providers: [PostService, LoggingService],
35 | })
36 | export class AppModule {
37 | }
38 |
--------------------------------------------------------------------------------
/src/ts/dashboard/components/dashboard.component.ts:
--------------------------------------------------------------------------------
1 | import {Post} from "../../shared/models/post";
2 | import {PostService} from "../../shared/services/post.service";
3 | import {Component, OnDestroy, OnInit} from "@angular/core";
4 | import {Observable} from "rxjs/Observable";
5 | import {AnonymousSubscription} from "rxjs/Subscription";
6 |
7 | @Component({
8 | selector: "dashboard",
9 | templateUrl: "/src/html/dashboard/dashboard.html",
10 | })
11 | export class DashboardComponent implements OnInit, OnDestroy {
12 |
13 | private timerSubscription: AnonymousSubscription;
14 | private postsSubscription: AnonymousSubscription;
15 | private posts: Post[];
16 | private post: Post;
17 |
18 | constructor(private postService: PostService) {
19 | this.post = new Post();
20 | }
21 |
22 | public ngOnInit(): void {
23 | this.refreshData();
24 | }
25 |
26 | public ngOnDestroy(): void {
27 | if (this.postsSubscription) {
28 | this.postsSubscription.unsubscribe();
29 | }
30 | if (this.timerSubscription) {
31 | this.timerSubscription.unsubscribe();
32 | }
33 | }
34 |
35 | public save(): void {
36 | this.postService
37 | .save(this.post)
38 | .subscribe(post => {
39 | this.posts.unshift(post);
40 | this.post = new Post();
41 | });
42 | }
43 |
44 | public deletePost(postToDelete: Post, event: any): void {
45 | event.stopPropagation();
46 | this.postService.delete(postToDelete).subscribe(() => {
47 | this.posts = this.posts.filter((post: Post) => post.id !== postToDelete.id);
48 | });
49 | }
50 |
51 | private refreshData(): void {
52 | this.postsSubscription = this.postService.getPosts().subscribe(posts => {
53 | this.posts = posts;
54 | this.subscribeToData();
55 | });
56 | }
57 |
58 | private subscribeToData(): void {
59 | this.timerSubscription = Observable.timer(5000).first().subscribe(() => this.refreshData());
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/src/ts/main.ts:
--------------------------------------------------------------------------------
1 | import {AppModule} from "./app.module";
2 | import {platformBrowserDynamic} from "@angular/platform-browser-dynamic";
3 |
4 | platformBrowserDynamic().bootstrapModule(AppModule);
5 |
--------------------------------------------------------------------------------
/src/ts/post/components/post.component.ts:
--------------------------------------------------------------------------------
1 | import {Post} from "../../shared/models/post";
2 | import {PostService} from "../../shared/services/post.service";
3 | import {Comment} from "../models/comment";
4 | import {CommentService} from "../services/comment.service";
5 | import {Component, OnDestroy, OnInit} from "@angular/core";
6 | import {ActivatedRoute, Params, Router} from "@angular/router";
7 | import {Observable} from "rxjs/Observable";
8 | import {AnonymousSubscription} from "rxjs/Subscription";
9 |
10 | @Component({
11 | providers: [CommentService],
12 | selector: "bid",
13 | templateUrl: "src/html/post/post.html",
14 | })
15 | export class PostComponent implements OnInit, OnDestroy {
16 |
17 | private static ID_ROUTE_PARAM: string = "id";
18 | private timerSubscription: AnonymousSubscription;
19 | private commentsSubscription: AnonymousSubscription;
20 | private post: Post;
21 | private comments: Comment[];
22 | private comment: Comment;
23 |
24 | constructor(private postService: PostService, private commentService: CommentService,
25 | private route: ActivatedRoute, private router: Router) {
26 | }
27 |
28 | public ngOnInit(): void {
29 | this.comment = new Comment();
30 | this.route.params.forEach((params: Params) => {
31 | if (params[PostComponent.ID_ROUTE_PARAM] !== undefined) {
32 | let id: number = +params[PostComponent.ID_ROUTE_PARAM];
33 | this.postService.getPost(id).subscribe(post => {
34 | this.post = post;
35 | this.comment = new Comment();
36 | this.comment.postId = this.post.id;
37 | this.refreshData();
38 | });
39 | } else {
40 | this.router.navigate(["/dashboard"]);
41 | }
42 | });
43 | }
44 |
45 | public ngOnDestroy(): void {
46 | if (this.commentsSubscription) {
47 | this.commentsSubscription.unsubscribe();
48 | }
49 | if (this.timerSubscription) {
50 | this.timerSubscription.unsubscribe();
51 | }
52 | }
53 |
54 | public save(): void {
55 | this.commentService
56 | .save(this.comment)
57 | .subscribe(comment => {
58 | this.comments.unshift(comment);
59 | this.comment = new Comment();
60 | this.comment.postId = this.post.id;
61 | });
62 | }
63 |
64 | public deleteComment(comment: Comment, event: any): void {
65 | event.stopPropagation();
66 | this.commentService
67 | .delete(comment)
68 | .subscribe(() => {
69 | this.comments = this.comments.filter((returnableObjects: Comment) => {
70 | return returnableObjects.id !== comment.id;
71 | });
72 | });
73 | }
74 |
75 | private refreshData(): void {
76 | this.commentsSubscription = this.commentService.getComments(this.post.id).subscribe(comments => {
77 | this.comments = comments;
78 | this.subscribeToData();
79 | });
80 | }
81 |
82 | private subscribeToData(): void {
83 | this.timerSubscription = Observable.timer(5000).first().subscribe(() => this.refreshData());
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/src/ts/post/models/comment.ts:
--------------------------------------------------------------------------------
1 | export class Comment {
2 | public id: number;
3 | public postId: number;
4 | public content: string;
5 | }
6 |
--------------------------------------------------------------------------------
/src/ts/post/services/comment.service.ts:
--------------------------------------------------------------------------------
1 | import {LoggingService} from "../../shared/services/logging.service";
2 | import {Comment} from "../models/comment";
3 | import {Injectable} from "@angular/core";
4 | import {Headers, Http, Response} from "@angular/http";
5 | import {Observable} from "rxjs/Observable";
6 |
7 | @Injectable()
8 | export class CommentService {
9 | private postsUrl = "http://localhost:3000/posts/";
10 | private commentsUrl = "http://localhost:3000/comments/";
11 |
12 | constructor(private http: Http, private loggingService: LoggingService) {
13 | }
14 |
15 | public getComments(postId: number): Observable {
16 | return this.http.get(this.postsUrl + postId + "/comments?_sort=id&_order=DESC")
17 | .map(res => res.json())
18 | .catch(this.loggingService.handleError);
19 | }
20 |
21 | public save(comment: Comment): Observable {
22 | let headers = new Headers({
23 | "Content-Type": "application/json",
24 | });
25 |
26 | return this.http
27 | .post(this.postsUrl + comment.postId + "/comments", JSON.stringify(comment), {headers})
28 | .map(res => res.json())
29 | .catch(this.loggingService.handleError);
30 | }
31 |
32 | public delete(comment: Comment): Observable {
33 | let headers = new Headers();
34 | headers.append("Content-Type", "application/json");
35 |
36 | return this.http
37 | .delete(this.commentsUrl + comment.id, {headers})
38 | .map(res => res.json())
39 | .catch(this.loggingService.handleError);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/ts/rxjs-extensions.ts:
--------------------------------------------------------------------------------
1 | // Observable class extensions
2 | import "rxjs/add/observable/of";
3 | import "rxjs/add/observable/throw";
4 | import "rxjs/add/observable/timer";
5 |
6 | // Observable operators
7 | import "rxjs/add/operator/catch";
8 | import "rxjs/add/operator/debounceTime";
9 | import "rxjs/add/operator/distinctUntilChanged";
10 | import "rxjs/add/operator/do";
11 | import "rxjs/add/operator/filter";
12 | import "rxjs/add/operator/first";
13 | import "rxjs/add/operator/map";
14 | import "rxjs/add/operator/switchMap";
15 |
--------------------------------------------------------------------------------
/src/ts/shared/models/post.ts:
--------------------------------------------------------------------------------
1 | export class Post {
2 | public id: number;
3 | public title: String;
4 | }
5 |
--------------------------------------------------------------------------------
/src/ts/shared/services/logging.service.ts:
--------------------------------------------------------------------------------
1 | import {Injectable} from "@angular/core";
2 | import {Observable} from "rxjs/Observable";
3 |
4 | @Injectable()
5 | export class LoggingService {
6 |
7 | public handleError(error: any) {
8 | let errMsg = (error.message) ? error.message :
9 | error.status ? `${error.status} - ${error.statusText}` : "Server error";
10 | console.error(errMsg);
11 | return Observable.throw(errMsg);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/ts/shared/services/post.service.ts:
--------------------------------------------------------------------------------
1 | import {Post} from "../models/post";
2 | import {LoggingService} from "./logging.service";
3 | import {Injectable} from "@angular/core";
4 | import {Headers, Http, Response} from "@angular/http";
5 | import {Observable} from "rxjs/Observable";
6 |
7 | @Injectable()
8 | export class PostService {
9 | private postsUrl = "http://localhost:3000/posts/";
10 |
11 | constructor(private http: Http, private loggingService: LoggingService) {
12 | }
13 |
14 | public getPosts(): Observable {
15 | return this.http.get(this.postsUrl + "?_sort=id&_order=DESC")
16 | .map(res => res.json())
17 | .catch(this.loggingService.handleError);
18 | }
19 |
20 | public getPost(id: number): Observable {
21 | return this.http.get(this.postsUrl + id)
22 | .map(res => res.json())
23 | .catch(this.loggingService.handleError);
24 | }
25 |
26 | public save(post: Post): Observable {
27 | let headers = new Headers({
28 | "Content-Type": "application/json",
29 | });
30 |
31 | return this.http
32 | .post(this.postsUrl, JSON.stringify(post), {headers})
33 | .map(res => res.json())
34 | .catch(this.loggingService.handleError);
35 | }
36 |
37 | public delete(post: Post): Observable {
38 | let headers = new Headers();
39 | headers.append("Content-Type", "application/json");
40 |
41 | return this.http
42 | .delete(this.postsUrl + post.id, {headers})
43 | .map(res => res.json())
44 | .catch(this.loggingService.handleError);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/system-config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * System configuration for Angular samples
3 | * Adjust as necessary for your application needs.
4 | */
5 | (function (global) {
6 | System.config({
7 | paths: {
8 | // paths serve as alias
9 | 'npm:': 'node_modules/'
10 | },
11 | // map tells the System loader where to look for things
12 | map: {
13 | // our app is within the app folder
14 | app: 'app/js',
15 |
16 | // angular bundles
17 | '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
18 | '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
19 | '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
20 | '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
21 | '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
22 | '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
23 | '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
24 | '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
25 | '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
26 |
27 | // other libraries
28 | 'rxjs': 'npm:rxjs'
29 | },
30 |
31 | // packages tells the System loader how to load when no filename and/or no extension
32 | packages: {
33 | app: {
34 | main: './main.js',
35 | defaultExtension: 'js'
36 | },
37 | api: {defaultExtension: 'js'},
38 | rxjs: {
39 | defaultExtension: 'js'
40 | },
41 | }
42 | });
43 | })(this);
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES5",
4 | "module": "system",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "removeComments": false,
10 | "noImplicitAny": false,
11 | "outDir": "app/js"
12 | },
13 | "exclude": [
14 | "node_modules"
15 | ]
16 | }
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tslint:latest",
3 | "rules": {
4 | }
5 | }
--------------------------------------------------------------------------------