kat kat - 10 months ago 81
AngularJS Question

How do I pass an Angular object to a Javascript function in a Google Chrome extension?

I am building a Google chrome extension that "scrapes" the DOM of a particular website for objects and processes them in javascript functions.

Currently I am using the chrome.tabs.query API to perform operations in the background page. I was able to pull data out of the url with

chrome.tabs.query({ 'active': true, 'lastFocusedWindow': true }, function (tabs) {
var url = tabs[0].url;
var s = url.split('?')[1];
var installation = s.split('&')[0];
full_url = 'http://domain.com/' + url;
window.open(full_url, '_blank');

But now I am trying to pass an Angular object from the DOM of the page to a similar function:

chrome.tabs.query({ "active": true, "lastFocusedWindow": true }, function (tabs) {
var dom_el = this.document.querySelector('[ng-controller="chartNewController"]');
var ng_el = this.angular.element(dom_el);
var ng_el_scope = this.ng_el.scope();
var address = this.ng_el_scope.fullAddress;

And I get the following error:

Cannot read property 'querySelector' of undefined
at null.callback

I am not sure I am going about the is the most efficient way so my question is what is the most optimal way to "scrape" Angular objects in the DOM of a background HTML page in regards to building a chrome extension?

Answer Source

There are two errors for the following line:

var dom_el = this.document.querySelector('[ng-controller="chartNewController"]');
  1. this means the callback, there is no property document for this object
  2. Event if you directly use document.querySelector..., you would be still unable to get the element, since when you call this line in background page, document points to background page document rather than the web page.

One suggestion would be using Message Passing to get the value, you would need a content script and establish communication between it and background page.

Background page:

chrome.tabs.query({ "active": true, "lastFocusedWindow": true }, function (tabs) {
    chrome.tabs.sendMessage(tabs[0].id, {action: 'get'}, function(response) {

Content script (You would need to retrieve the correct angular object, that depends on your web page, I can't help with that):

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
    if(request.action === 'get') {
        var dom_el = document.querySelector('[ng-controller="chartNewController"]');
        // Ensure retrieving the correct angular object (The previous this object), that depends on your web page environment.
        var ng_el = angular.element(dom_el);
        var ng_el_scope = ng_el.scope();
        var address = ng_el_scope.fullAddress;
        sendResponse({ address: address });