├── src ├── app │ ├── home │ │ ├── index.ts │ │ ├── home.component.html │ │ └── home.component.ts │ ├── _services │ │ ├── index.ts │ │ └── message.service.ts │ ├── main.ts │ ├── app.routing.ts │ ├── app.module.ts │ ├── app.component.html │ └── app.component.ts ├── polyfills.ts ├── main.ts └── index.html ├── README.md ├── tsconfig.json ├── .gitignore ├── webpack.config.js ├── LICENSE └── package.json /src/app/home/index.ts: -------------------------------------------------------------------------------- 1 | export * from './home.component'; -------------------------------------------------------------------------------- /src/app/_services/index.ts: -------------------------------------------------------------------------------- 1 | export * from './message.service'; 2 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | import 'core-js/es6/reflect'; 2 | import 'core-js/es7/reflect'; 3 | import 'zone.js/dist/zone'; -------------------------------------------------------------------------------- /src/app/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | 3 | import { AppModule } from './app.module'; 4 | 5 | platformBrowserDynamic().bootstrapModule(AppModule); -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import './polyfills'; 2 | 3 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 4 | import { AppModule } from './app/app.module'; 5 | platformBrowserDynamic().bootstrapModule(AppModule); -------------------------------------------------------------------------------- /src/app/home/home.component.html: -------------------------------------------------------------------------------- 1 |

Angular 7 Component Communication

2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # angular-7-communicating-between-components 2 | 3 | Angular 7 - Communicating Between Components with Observable & Subject 4 | 5 | To see a demo and further details go to http://jasonwatmore.com/post/2019/02/07/angular-7-communicating-between-components-with-observable-subject 6 | -------------------------------------------------------------------------------- /src/app/app.routing.ts: -------------------------------------------------------------------------------- 1 | import { Routes, RouterModule } from '@angular/router'; 2 | 3 | import { HomeComponent } from './home/index'; 4 | 5 | const appRoutes: Routes = [ 6 | { path: '', component: HomeComponent }, 7 | 8 | // otherwise redirect to home 9 | { path: '**', redirectTo: '' } 10 | ]; 11 | 12 | export const routing = RouterModule.forRoot(appRoutes); -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "emitDecoratorMetadata": true, 4 | "experimentalDecorators": true, 5 | "lib": [ "es2015", "dom" ], 6 | "module": "commonjs", 7 | "moduleResolution": "node", 8 | "noImplicitAny": true, 9 | "sourceMap": true, 10 | "suppressImplicitAnyIndexErrors": true, 11 | "target": "es5" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/app/_services/message.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Observable, Subject } from 'rxjs'; 3 | 4 | @Injectable({ providedIn: 'root' }) 5 | export class MessageService { 6 | private subject = new Subject(); 7 | 8 | sendMessage(message: string) { 9 | this.subject.next({ text: message }); 10 | } 11 | 12 | clearMessages() { 13 | this.subject.next(); 14 | } 15 | 16 | getMessage(): Observable { 17 | return this.subject.asObservable(); 18 | } 19 | } -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Angular 7 - Communicating Between Components with Observable & Subject 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | Loading... 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | 4 | import { AppComponent } from './app.component'; 5 | import { routing } from './app.routing'; 6 | 7 | import { HomeComponent } from './home'; 8 | 9 | @NgModule({ 10 | imports: [ 11 | BrowserModule, 12 | routing 13 | ], 14 | declarations: [ 15 | AppComponent, 16 | HomeComponent 17 | ], 18 | bootstrap: [AppComponent] 19 | }) 20 | 21 | export class AppModule { } -------------------------------------------------------------------------------- /src/app/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { MessageService } from '../_services/index'; 4 | 5 | @Component({ templateUrl: 'home.component.html' }) 6 | export class HomeComponent { 7 | constructor(private messageService: MessageService) { } 8 | 9 | sendMessage(): void { 10 | // send message to subscribers via observable subject 11 | this.messageService.sendMessage('Message from Home Component to App Component!'); 12 | } 13 | 14 | clearMessages(): void { 15 | // clear messages 16 | this.messageService.clearMessages(); 17 | } 18 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | typings 33 | 34 | # Optional npm cache directory 35 | .npm 36 | 37 | # Optional REPL history 38 | .node_repl_history 39 | 40 | # Generated files 41 | dist -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
{{message.text}}
7 | 8 |
9 |
10 |
11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 2 | 3 | module.exports = { 4 | entry: './src/main.ts', 5 | module: { 6 | rules: [ 7 | { 8 | test: /\.ts$/, 9 | use: ['ts-loader', 'angular2-template-loader'], 10 | exclude: /node_modules/ 11 | }, 12 | { 13 | test: /\.(html|css)$/, 14 | loader: 'raw-loader' 15 | }, 16 | ] 17 | }, 18 | resolve: { 19 | extensions: ['.ts', '.js'] 20 | }, 21 | plugins: [ 22 | new HtmlWebpackPlugin({ 23 | template: './src/index.html', 24 | filename: 'index.html', 25 | inject: 'body' 26 | }) 27 | ], 28 | optimization: { 29 | splitChunks: { 30 | chunks: 'all', 31 | }, 32 | runtimeChunk: true 33 | }, 34 | devServer: { 35 | historyApiFallback: true 36 | } 37 | }; -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnDestroy } from '@angular/core'; 2 | import { Subscription } from 'rxjs'; 3 | 4 | import { MessageService } from './_services/index'; 5 | 6 | @Component({ 7 | selector: 'app', 8 | templateUrl: 'app.component.html' 9 | }) 10 | 11 | export class AppComponent implements OnDestroy { 12 | messages: any[] = []; 13 | subscription: Subscription; 14 | 15 | constructor(private messageService: MessageService) { 16 | // subscribe to home component messages 17 | this.subscription = this.messageService.getMessage().subscribe(message => { 18 | if (message) { 19 | this.messages.push(message); 20 | } else { 21 | // clear messages when empty message received 22 | this.messages = []; 23 | } 24 | }); 25 | } 26 | 27 | ngOnDestroy() { 28 | // unsubscribe to ensure no memory leaks 29 | this.subscription.unsubscribe(); 30 | } 31 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Jason Watmore 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. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-7-communicating-between-components", 3 | "version": "1.0.0", 4 | "repository": { 5 | "type": "git", 6 | "url": "https://github.com/cornflourblue/angular-7-communicating-between-components.git" 7 | }, 8 | "scripts": { 9 | "build": "webpack --mode production", 10 | "start": "webpack-dev-server --mode development --open" 11 | }, 12 | "license": "MIT", 13 | "dependencies": { 14 | "@angular/common": "^7.0.1", 15 | "@angular/compiler": "^7.0.1", 16 | "@angular/core": "^7.0.1", 17 | "@angular/forms": "^7.0.1", 18 | "@angular/platform-browser": "^7.0.1", 19 | "@angular/platform-browser-dynamic": "^7.0.1", 20 | "@angular/router": "^7.0.1", 21 | "core-js": "^2.5.7", 22 | "rxjs": "^6.3.3", 23 | "zone.js": "^0.8.26" 24 | }, 25 | "devDependencies": { 26 | "@types/node": "^10.0.4", 27 | "angular2-template-loader": "^0.6.2", 28 | "html-webpack-plugin": "^3.2.0", 29 | "raw-loader": "^1.0.0", 30 | "ts-loader": "^5.3.3", 31 | "typescript": "^3.3.1", 32 | "webpack": "^4.29.0", 33 | "webpack-cli": "^3.2.1", 34 | "webpack-dev-server": "^3.1.4" 35 | } 36 | } 37 | --------------------------------------------------------------------------------