3

I am working on chrome extension. I have a background.js to fetch data in specific conditions.

  1. When the conditions meet am activating the pageAction
  2. By the time user clicks extension icon I am sending a message to "background.js" and "background.js" replying me with data.

Although i'm updating component property but the change is not reflecting the UI.

background.js

chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
  sendResponse(this.data);
});

app.component.ts

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


// @ts-ignore
const CHROME = chrome;


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  title = 'Title';
  response: any;

  constructor() {}

  ngOnInit() {
    CHROME.runtime.sendMessage({
      message: 'Give me data'
    }, response => {
      this.title = response.title;
      this.response = JSON.stringify(response);
      console.log(response.title);
    });
  }

  clickMe() {
    console.log('Before:' + this.title);
    this.title +=  ' !!';
  }
}

app.component.html

  <div style="text-align:center">
   <h1> Title: {{title}}</h1>
   <h1> Response: {{response}}</h1>
  </div>

<button (click)="clickMe()" >Click Me!</button>

As far as I concerned, I am updating app.component's property from another scope because of that Angular can't realize the data changed.

I have added a button when I click the button Angular detect the "title" field has been changed so it updates the UI.

How can I update UI from another context?


Update

Because of the changes has been made in another scope Angular couldn't detect the changes, so I have to force it:

constructor(private changeDetectorRef: ChangeDetectorRef) {}

  ngOnInit() {
    CHROME.runtime.sendMessage({
      message: 'Give me data'
    }, response => {
      //...
      this.changeDetectorRef.detectChanges();
    });
  }
Muhammed Ozdogan
  • 5,341
  • 8
  • 32
  • 53

1 Answers1

-1

I'm not really sure why you're using a Subject in the first place when you have everything in the same Component. Try getting rid of that and use the ngOnInit instead of the constructor.

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

// @ts-ignore
const CHROME = chrome;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  title = 'Title';
  response: any;

  constructor() {}

  ngOnInit() {
    CHROME.runtime.sendMessage({
      message: 'Give me data'
    }, response => {
      this.title = response.title;
      this.response = response;
    });
  }
}
SiddAjmera
  • 38,129
  • 5
  • 72
  • 110