I am new in Angular filed! So far I have liked but facing some difficulty in this following case. I want to send data from one component to another component once the user clicks a specific cell with href tag in the Datatables. Therefore I have created following .ts file
service.ts
import { Injectable } from '@angular/core';
import { HttpClient,HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { BehaviorSubject } from 'rxjs';
@Injectable()
export class MyService {
private protDataSource = new BehaviorSubject<any>({
currentprotData:null
});
currentprotData= this.protDataSource.asObservable();
constructor(
private http: HttpClient
) {}
sendProtData(currentprotData:any){
console.log(currentprotData)
this.protDataSource.next(currentprotData);
}
get(url){
return this.http.get(url)
.pipe(
map(responce=>responce),
catchError(this.handleError)
)
}
}
sender.ts
import { Component, OnInit, OnDestroy, ViewChild, Renderer } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { DataTableDirective } from 'angular-datatables';
import { HttpClient,HttpErrorResponse } from '@angular/common/http';
import { Subject } from 'rxjs';
import { MyService } from '../qmpkb/qmpkb.service';
declare var jquery: any;
@Component({
selector: 'app-sender-page',
templateUrl: './sender.component.html',
styleUrls: ['./sender.component.css'],
providers:[MyService]
})
export class SenderComponent implements OnInit,OnDestroy {
dtOptions: DataTables.Settings = {};
dtTrigger: Subject<any> = new Subject();
private routeSub:any;
errorStr:Boolean;
@ViewChild(DataTableDirective)
datatableElement: DataTableDirective;
constructor(
private route: ActivatedRoute,
private http: HttpClient,
private renderer: Renderer,
private router: Router,
private _myserve:MyService
) { }
ngOnInit(): void {
//let destPath='fileapi/resultFile/jsonData/resultJson/'+this.queryResPath
let destPath='assets/json/fake.json'
this.dtOptions = {
pagingType: 'full_numbers',
ajax: destPath,
processing: true,
serverSide: false,
columns: [
{
title: 'Prot Seq',
render: function (data: any, type: any, row: any, meta) {
if (row["Prot Seq"].trim().length > 0 ){
var array =(row["Prot Seq"].trim()).split('<br>');
array.forEach(function(element, index) {
array[index] ='<a target="_blank" href="/seqfeatures" routerLinkActive="active" seq-link-id=' + element+'>'+element+'</a>';
});
return array.join("<br>");
} else {
return 'No';
}
}
}
]
};
}
ngAfterViewInit(): void {
this.renderer.listenGlobal('document', 'click', (event) => {
if (event.target.hasAttribute("seq-link-id")) {
this._qmpkb.get(url).subscribe((response: any)=>{
this._myserve.sendProtData(response);
}, error=>{
this.errorStr = error;
})
}
})
}
ngOnDestroy(){
this.routeSub.unsubscribe();
this.dtTrigger.unsubscribe();
}
}
receiver.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { HttpClient,HttpErrorResponse } from '@angular/common/http';
import { MyService } from '../qmpkb/qmpkb.service';
declare var require: any
@Component({
selector: 'app-prot-view',
templateUrl: './prot-view.component.html',
styleUrls: ['./prot-view.component.css'],
providers:[MyService]
})
export class ProtViewComponent implements OnInit,OnDestroy {
message:string
constructor(
private route: ActivatedRoute,
private http: HttpClient,
private router: Router,
private _myserve:MyService,
) { }
ngOnInit() {
this._myserve.currentprotData.subscribe(currentprotData=>{
this.message=currentprotData
})
}
ngAfterViewInit(): void {
console.log(this.message)
}
ngOnDestroy(){
}
}
My service can recive data but reciver always retrun null. I am curius to know what is going wrong here! I really apprecite your help and advice!
Updated As DeborahK suggested to include part of project on stackblitz! You can check how I am trying to build this project!
There are few problems.Easy way is if you are subscribing to sendProtData().subscribe
in receiver.ts
that's wrong. You need to subscribe to BehaviorSubject
and sendProtData()
has no return type as well.
Make protDataSource
as public and subscribe to it.
public protDataSource = new BehaviorSubject<any>({
currentprotData:null
});
and then in receiver.ts:
ngOnInit() {
this._myserve.protDataSource.subscribe(currentprotData=>{
this.message=currentprotData
})
This so do the trick.
UPDATE:
I fixed below things to make it work:
You should not inject service using provider:[]
@Component
. It creates a new instance of service for each component. . You dont need that. You need both component to share same service instance to share the data. So, inject in @NgModule
in app.module.ts
In the demo code, there was no <app-receiver></app-receiver>
. I added that as well so as to initiate the component.
I hope it helped :) . Thanks for creating a demo