justforp basnet
justforp basnet

Reputation: 85

Uncaught TypeError: Cannot read property 'create' of undefined in chrome extension

I am trying to develop the chrome extension where when user selects the text, that selected text will be grabbed and then send to the background script for processing the api call. Right now, the text is grabbed but i have consoled in the following line

background.js

chrome.extension.onMessage.addListener(function(request, sender, sendResponse){
    console.log('req', request.message)

but this is not consoled perhaps due to this block is not even called.

Here is the code

manifest.json

{
  "manifest_version": 2,
  "name": "DEMO",
  "description": "This extension allow the user to select the text and redirect to the google to search that text",
  "version": "1.0",
  "browser_action": {
    "default_icon": "Logo.png",
    "default_popup": "html/popup.html",
    "default_title": "click me"
  },
  "permissions": [
    "activeTab",
    "storage"
  ],
  "options_page": "html/popup.html",
  "background": {
    "scripts": ["js/eventPage.js", "js/background.js"],
    "persistent": false
  },
  "content_scripts": [
    {
        "matches" : [
            "http://*/*", "https://*/*"
        ],
        "js" : [
            "js/content.js"
        ]
    }
],
  "commands": {
          "toggle-feature-foo": {
            "suggested_key": {
              "default": "Ctrl+Shift+Y",
              "mac": "Command+Shift+H"
            },
            "description": "Toggle feature foo"
          }
        }
}

content.js

function init(event) {
  var topic = "";
  if (window.getSelection) {
    topic = window.getSelection().toString();
  } else if (document.selection) {
      topic = document.selection.createRange().topic;
  } else {
    return topic;
  }
  if((event.ctrlKey && event.keyCode === 65) && topic.length) {
    chrome.extension.sendMessage({'message': 'setTopic', 'data': topic}, function(response){
      console.log('response', response);
    })
  }
}

document.addEventListener('keydown',init);

background.js

var selectedTopic = null;

  chrome.extension.onMessage.addListener(function(request, sender, sendResponse){
    console.log('req', request.message) // not listened 
    switch(request.message) {
      case 'setTopic':
        window.selectedTopic = request.data;
      break;
      default:
        sendResponse({data: 'Invalid'})
      break;
    }
  })

  function savetopic(info, tab) {
    var httpRequest = new XMLHttpRequest();
    httpRequest.open('get', 'http://www.google.com/?q='+selectedTopic)
    httpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    httpRequest.onreadystatechange = function() {
    if(httpRequest.readyState==4) {
      alert(httpRequest.responseText);
    }
  }
}

var contexts = ["selection"];
for (var i = 0; i < contexts.length; i++)
{
    var context = contexts[i];
    chrome.contextMenus.create({"title": "Send to Google", "contexts":[context], "onclick": savetopic});
}

This is the full code of my chrome extension. Did i miss something in the background.js ? I have even that in manifest.json as

"background": {
    "scripts": ["js/eventPage.js", "js/background.js"],
    "persistent": false
  },

why it is not working? I checked in the background from the inspect views of extension setting and it shows me the following error in the console

Uncaught TypeError: Cannot read property 'create' of undefined

Upvotes: 2

Views: 7278

Answers (1)

Andreas Moldskred
Andreas Moldskred

Reputation: 315

For your messaging part your problem should be that you are using chrome.extension.onMessage and chrome.extension.sendMessage.

For messaging in chrome you would do this:

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log('req', request.message) // not listened 
    switch(request.message) {
     case 'setTopic':
      window.selectedTopic = request.data;
      break;
     default:
      sendResponse({data: 'Invalid'})
      break;
    }
  });

and

chrome.runtime.sendMessage({'message': 'setTopic', 'data': topic}, function(response){
  console.log('response', response);
  });

You can read more about it here: https://developer.chrome.com/apps/messaging

Also, for chrome commands api, which you are using, you want to handle commands in the background like this:

chrome.commands.onCommand.addListener(function(command) {
        console.log('Command:', command);
      });

instead of doing the hassle of messaging everywhere.

Read about it here: https://developer.chrome.com/apps/commands

Upvotes: 1

Related Questions