1

I have create two component: 1. create-articles : is used to create article. 2. List Articles : is used to list all the articles.

Parent component is Home Component

import { Component, OnInit } from '@angular/core';


@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']

})
export class HomeComponent implements OnInit {
  constructor() { 
    
  }

  ngOnInit() {
  }

}
<div class="container">
    <div class="row">
        <div class="col-md-4">
            <articles-form></articles-form>
        </div>
        <div class="col-md-4">
            <articles></articles>
        </div>

    </div>
</div>

i want to reresh the article list component whenever article is created.

import { Component, OnInit } from '@angular/core';
import { ArticlesService } from '../../services/articles.service';
import { Article } from '../../models/article.model';
import { IArticles } from '../../interfaces/IArticles';
import { Observable } from 'rxjs';

@Component({
  selector: 'articles',
  templateUrl: './articles.component.html',
  styleUrls: ['./articles.component.css'],
  providers:[ArticlesService]
})
export class ArticlesComponent implements OnInit {

 articles: IArticles[];
 message:string;
 errorMessage:string;
 constructor(private as:ArticlesService) { }
 ngOnInit():void {
    this.fetchArticles();
 }
  
 fetchArticles(): void {
        this.as.getArticles()
       .subscribe( articles => {
            this.articles = articles
            console.log(this.articles);
        },
     error => this.errorMessage = <any>error);    
   };


}
<button class="btn btn-primary" (click)="fetchArticles()">
 Reload Data
</button>
<div class="table table-responsive">
 <table class="table table-bordered">
  <thead>
   <tr>
    <th>#</th>
    <th>Title</th>
   </tr>
  </thead>
  <tbody>
   <tr *ngFor="let article of articles;let i=index">
    <td>
     {{i+1}}
    </td>
    <td>
     {{article.articles.title}}
    </td>
   </tr>
  </tbody>
 </table>
</div>
import { Component, OnInit } from '@angular/core';
import { ArticlesService } from '../../services/articles.service';
import { Article } from '../../models/article.model';
import { IArticles } from '../../interfaces/IArticles';
import { Observable } from 'rxjs';
import { ArticlesComponent } from '../articles/articles.component';
import { EventEmitter, Input, Output } from '@angular/core';

@Component({
  selector: 'articles-form',
  templateUrl: './articles-form.component.html',
  styleUrls: ['./articles-form.component.css'],
  providers:[ArticlesService]
})
export class ArticlesFormComponent implements OnInit {
  books: IArticles[];
    article:IArticles=new Article(1,"Let Us C","Rahul Shaw","http://google.com");
  message:string;
  errorMessage:string;
  articles:IArticles[];
    constructor(private as:ArticlesService) { }

        ngOnInit():void {}

      onSubmit(data:IArticles) : void{
          var articles=this.as.createArticles(data)
          .subscribe( book => {
              this.message = "submitted"; 

          },
          error => this.errorMessage = <any>error);
      };

}
<div class="panel panel-primary">
    <div class="panel-body">
        <h1>Article Posting</h1>
        <form (ngSubmit)="onSubmit(article)">
            <div class="form-group">
              <label for="title">Title</label>
              <input type="text" class="form-control" id="title" required [(ngModel)]="article.title" name="title">
            </div>
            <div class="form-group">
              <label for="author">Author</label>
              <input type="text" class="form-control" id="author" required [(ngModel)]="article.author" name="author">
            </div>
            <div class="form-group">
              <label for="url">URL</label>
              <input type="text" class="form-control" id="url" [(ngModel)]="article.url" name="url">
            </div>
            <button type="submit" class="btn btn-default">      Submit
            </button>
            {{ name }}
        </form>
    </div>
</div>

i want to refresh the article list component whenever article is created.

  • Add your code and try – SPatel Jun 22 '18 at 04:38
  • your create and list articles are in same page? please make clear your question – AmiLinn Jun 22 '18 at 04:42
  • try using a service. – prady Jun 22 '18 at 04:50
  • Check the below mentioned repo of mine, it will show you how to communicate b/w components. Parent => Child Child => Parent https://github.com/immad-hamid/components-data-sharing – Immad Hamid Jun 22 '18 at 04:54
  • You can share data by using the `@Input()` decorator to allow data to be passed via the template, [Check here for more](https://angularfirebase.com/lessons/sharing-data-between-angular-components-four-methods/#Parent-to-Child-Sharing-Data-via-Input) – ElasticCode Jun 22 '18 at 04:55
  • you can use `@input` and `@output` for communicate with components. – vineet Jun 22 '18 at 04:55
  • Possible duplicate of [How to pass object from one component to another in Angular 2?](https://stackoverflow.com/questions/34088209/how-to-pass-object-from-one-component-to-another-in-angular-2) – ElasticCode Jun 22 '18 at 04:56
  • any one plz provide me the full code or alter the same code – Rahul Shaw Jun 22 '18 at 05:08
  • You have a few options, use `@Output()` and `@Input()` which will emit to your parent component then it will pass it to another child component. Use services or learn `@ngrx/store` – penleychan Jun 22 '18 at 05:10
  • @Rahul Shaw you can call `ArticlesComponent` component function `fetchArticles()` from your `ArticlesFormComponent` component. – Sanoj_V Jun 22 '18 at 05:15
  • @Sanoj_V Shall we call like this : ArticlesComponent.fetchArticles() – Rahul Shaw Jun 22 '18 at 05:23
  • @Rahul Shaw Yes why not. Take it a try?? Add in contructor `private ac:ArticlesComponent` and now call in subscriber method of `onSubmit` like this `this.ac.fetchArticles();` – Sanoj_V Jun 22 '18 at 05:33
  • @Sanoj_V It works but view not updated – Rahul Shaw Jun 22 '18 at 05:39
  • @Rahul Shaw you need to call `ngOnChange` method as well inside your `ArticlesComponent` component bacause child component always reflect in `ngOnChanges`.If this is not working then you need to pass list to `ArticlesComponent` from `onSubmit` function this is another option. – Sanoj_V Jun 22 '18 at 05:47
  • Any efficient way to do this task ?? – Rahul Shaw Jun 22 '18 at 06:00

3 Answers3

0

Possible Answer:-

Homecomponent.html(Parent)

<create-article  [data]="createarticleData"></create-article>
<list-article [data]="listarticleData"></list-article>

Homecomponent.ts(Parent)

createarticleData = "{"key":"value"}"
listarticleData= "{"key":"value"}"

create-article.component.ts

@Input data;

list-article.component.ts

@Input data;

For Calling a function:-

With type selector

@Component({
  selector: 'child-cmp',
  template: '<p>child</p>'
})
class ChildCmp {
  doSomething() {}
}
@Component({
  selector: 'some-cmp',
  template: '<child-cmp></child-cmp>',
  directives: [ChildCmp]
})
class SomeCmp {
  @ViewChild(ChildCmp) child:ChildCmp;
  ngAfterViewInit() {
    // child is set
    this.child.doSomething();
  }
}

With string selector

@Component({
  selector: 'child-cmp',
  template: '<p>child</p>'
})
class ChildCmp {
  doSomething() {}
}
@Component({
  selector: 'some-cmp',
  template: '<child-cmp #child></child-cmp>',
  directives: [ChildCmp]
})
class SomeCmp {
  @ViewChild('child') child:ChildCmp;
  ngAfterViewInit() {
    // child is set
    this.child.doSomething();
  }
}
Mahi
  • 3,748
  • 4
  • 35
  • 70
  • Hello Ahmad, this code is not working or i'm not able to write in a proper place. will you please provide more clear code as i'm beginner in angular2 – Rahul Shaw Jun 22 '18 at 05:01
0

There are many ways to skin a cat.

You have 3 components:

  1. HomeComponent - has child components ArticlesFormComponent & ArticlesComponent
  2. ArticlesFormComponent - A component with a form to create new Articles.
  3. ArticlesComponent - A component to fetch and list all Articles.

The idea is that you are already fetching the list of articles for ArticlesComponent and you are probably storing it in some array like articlesArray, so when you create a new article from ArticlesFormComponent, you fire a http request and if it returns a success response, you can add that article to the already existing articlesArray, and it will automatically be affected in ArticlesComponent.

You already have an ArticlesService which handles the http request, but since your ArticlesService is provided in the component level, it has different instances. It will be better to provide your ArticlesService in the module level so that your application will have a single instance.

@NgModule({
    ...
    providers:[
         ...,
         ArticlesService
    ]
})
export class AppModule { }
j4rey
  • 2,582
  • 20
  • 34
0

You can communicate with components in Different Way.

create a service to emit event from child to parent via subject so that you can subscribe the data any where in the app and it will be update automatically

Check the example snippet below

<div class="container">
    <div class="row">
        <div class="col-md-4">
            <app-articles-form></app-articles-form>
        </div>
        <div class="col-md-4">
            <app-articles></app-articles>
        </div>

    </div>
</div>

check the example:https://stackblitz.com/edit/angular-jncwsq

Chellappan வ
  • 23,645
  • 3
  • 29
  • 60