Search code examples
angularangular-materialangular-reactive-formsangular-servicesangular-forms

How to get response data of dialog box returned by a service after dialog box is closed inside parent component in angular


I created interfaces for passing data to dialog box to act as reusable component.

companynews-interfaces.ts

export interface ConfirmDialogData {
    title: string;
    description: string;
    imageSrc: string;
    showText: boolean;
    modalFormData: any;
}

I'm calling the above interfaces in parent component for dialog box to open

create-news.component.ts -- parent component

  openDialog(){
    this.companyNewsDialogServiceService.confirmDialog({
      title: 'CardImage',
      description: 'Card Image Description',
      imageSrc: "",
      modalFormData: "",
      showText: false
    });
  }

    openPersonDialog(){
    this.companyNewsDialogServiceService.confirmDialog({
      title: 'Responsible Person Image',
      description: 'Responsible Person Image Description',
      imageSrc: "",
      modalFormData: "",
      showText: true
    }); 
  }

  openAssetDialog(){
    this.companyNewsDialogServiceService.confirmDialog({
      title: 'Assets Image',
      description: 'Assets Image Description',
      imageSrc: "",
      modalFormData: "",
      showText: true
    }); 
  }

The above functions intern calling confirmDialog function defined in company-news-dialog-service.service.ts to pass interface data defined in the create-news.component.ts for respective dialogbox

Below is the company-news-dialog-service.service.ts file

company-news-dialog-service.service.ts

@Injectable({
  providedIn: 'root'
})
export class CompanyNewsDialogServiceService {
  recivedFormData: any;
  constructor(private dialog : MatDialog) { }
  confirmDialog(data: ConfirmDialogData) {
    debugger
    return this.dialog.open(UploadFileDialogComponent, {data}).afterClosed().subscribe(res =>{
      this.recivedFormData = res;
      console.log('formdata',this.recivedFormData)
    });
  }
}

In the above code I'm getting the response data from my dialog-box component(upload-file.component) after dialog box gets closed.

Below is the dialog-boxt(upload-file.component) component code

upload-file.component.ts -- child component

import { Component, ElementRef, EventEmitter, Inject, OnInit, Output, VERSION, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { FileUploadService } from 'projects/shared-lib/src/lib/file-upload.service';
import { ConfirmDialogData } from 'projects/shared-lib/src/lib/shared-interfaces/companynews-interfaces';
// import { ConfirmDialogData } from 'projects/shared-lib/src/lib/shared-interfaces/pagination-interfaces';

@Component({
  selector: 'app-upload-file-dialog',
  templateUrl: './upload-file-dialog.component.html',
  styleUrls: ['./upload-file-dialog.component.scss']
})

export class UploadFileDialogComponent implements OnInit {
  fileType: boolean;
  linkType: boolean;
  file: any;
  fileUploadPending = true;
  message: string;
  modalFormData: any;
  imagePath: any;
  dataimage: any;
  show: boolean = true;
  uploadedImagePath: string;
  allLanguages: string[] = ['en', 'de', 'fr', 'ar', 'zh'];
  selectedForm: FormGroup;
  selectedLanguage: string = 'en';
  @ViewChild('fileInput') fileInput: ElementRef;
  fileAttr = 'Choose File';
  constructor(private matdialogref: MatDialogRef<UploadFileDialogComponent>, private fb: FormBuilder, @Inject(MAT_DIALOG_DATA) public data: ConfirmDialogData, private fileUploadService: FileUploadService) {
   this.setForm()
  }

  ngOnInit(): void {
    console.log(this.matdialogref)
  }
  setForm(){
    this.selectedForm = this.fb.group({
      text: [''],
      link: [''],
      language: [this.selectedLanguage],
      filepath: [this.uploadedImagePath]
    })
    console.log("57", this.selectedForm)
  }
  get getLink(){
    return this.selectedForm.get('link')?.value == ""
  }
  onClickFile() {
    this.fileType = true;
    this.linkType = false
  }
  onClickLink() {
    this.fileType = false;
    this.linkType = true
  }
  onClose() {
    this.matdialogref.close()
  }
  onItemChange(value : any){
    console.log(value);
    let val = value.target.id;
    console.log(" Value is : ", val );
    if(val === "en"){  
    }
  }
  uploadFile() {
    debugger
    this.fileUploadService.UploadFile(this.file).subscribe((res: any) =>{
      console.log("83",res)
      console.log("83",res.data)
      console.log("83",res.data.uploadedFilePath)
      this.uploadedImagePath = res.data.uplodedFilePath
      this.setForm()
      this.modalFormData = this.selectedForm.value
      console.log("modal",this.modalFormData)
      this.matdialogref.close({data: this.modalFormData})
    })
  }
  removeOnClick() {
    this.show = !this.show;
    this.fileAttr = ''
  }
  uploadFileEvt(imgFile: any) {
    this.file = imgFile.target.files[0];
    console.log(this.file)
    if (imgFile.target.files && imgFile.target.files[0]) {
      this.fileAttr = '';
      Array.from(imgFile.target.files).forEach((file: any) => {
        this.fileAttr += file.name + ' - ';
      });

      // HTML5 FileReader API
      let reader = new FileReader();
      reader.onload = (e: any) => {
        let image = new Image();
        image.src = e.target.result;
        const [file] = imgFile.target.files;
        image.onload = rs => {
          let imgBase64Path = e.target.result;
          // console.log(imgBase64Path);
          this.data.imageSrc = imgBase64Path;
          console.log(this.data.imageSrc)
        };
      };
      reader.readAsDataURL(imgFile.target.files[0]);

      // Reset if duplicate image uploaded again
      this.fileInput.nativeElement.value = "";
      this.show = false
    } else {
      this.fileAttr = 'Choose File';
    }
  }
  getAssetType(){

  }
  selectLanguage(language : any){
    this.selectedLanguage = language;
    console.log(this.selectedLanguage)
  }
}

In the above code inside the uploadFile() function I'm passing formvalues collected from the input fields and also filepath returned by upload-file endpoint - (text, link, language, filepath) as modalFormData after dialogbox is closed.

modal form data

I'm recieving this data in company-news-dialog-service.service.ts service file as response as shown in the below screenshot.

response data from dialog box

I need the response data returned from the company-news-dialog-service.service.ts in create-news.component.ts.


Solution

  • Since your CompanyNewsDialogServiceService is already subscribed to the dialog being closed, what you need is to create a new "subscribable" property on that service, so that any component that has called confirmDialog method can get that data when it becomes available

    export class CompanyNewsDialogService {
      recivedFormData: any;
      
      dataReceived: Subject = new Subject()  ; // create a new Subject
      
      constructor(private dialog : MatDialog) { }
      
      confirmDialog(data: ConfirmDialogData) {
        debugger
        return this.dialog.open(UploadFileDialogComponent, {data}).afterClosed().subscribe(res =>{
          this.recivedFormData = res;
          dataReceived.next(res) ; //to notifiy the subscribed parent/component 
        });
      }
    }
    

    Then when you open the dialog you subscribe to that dataReceived subject.

    openDialog(){
        //subscribe to the subject of the service 
        this.companyNewsDialogService.dataReceived.subscribe(data => console.log(data))
    
        this.companyNewsDialogService.confirmDialog({
          title: 'CardImage',
          description: 'Card Image Description',
          imageSrc: "",
          modalFormData: "",
          showText: false
        });
    }
    

    Also consider renaming your service from CompanyNewsDialogServiceService to CompanyNewsDialogService

    For more details https://www.tektutorialshub.com/angular/subjects-in-angular/