Having difficulty retrieving the YouTube Username with JavaScript in a Chrome Extension

I am currently learning how to develop chrome extensions. My goal is to create a basic extension that logs the title of the current YouTube video in the console.

This snippet represents the HTML structure for the YouTube Title:

<div id="title" class="style-scope ytd-watch-metadata">
    <ytd-badge-supported-renderer class="style-scope ytd-watch-metadata" disable-upgrade="" hidden="">
    </ytd-badge-supported-renderer>
    <h1 class="style-scope ytd-watch-metadata">
      <yt-formatted-string force-default-style="" class="style-scope ytd-watch-metadata">Elon’s "based" Grok AI has entered the chat…</yt-formatted-string>
    </h1>
    <ytd-badge-supported-renderer class="style-scope ytd-watch-metadata" disable-upgrade="" hidden="">
    </ytd-badge-supported-renderer>
  </div>

Below is the code I have written to retrieve the title, located within the ContentScript:

(()=>{
    console.log(document.getElementById("title"));
    console.log(document.querySelector("#title > h1 > yt-formatted-string"));
})();

The first line outputs

<div id="title" class="style-scope ytd-watch-metadata">

But the second line returns

null

When I try this in the Chrome console, the second line performs as expected. It's not working properly when executed using JavaScript.

Here is my manifest.json file:

{
    "manifest_version": 3,
    "name": "FillModule",
    "description": "Fill test 001",
    "version": "1.0.0",
    "permissions": ["storage", "tabs"],
    "author":"Aniket Vishwakarma",
    "action": {
        "default_icon": "assets/doggy.png",
        "default_title": "Fill",
        "default_popup": "popup/popup.html"
    },
    "background" : {
        "service_worker": "background/background.js"
    },
    "content_scripts": [
        {
          "matches": ["https://*.youtube.com/*"],
          "js": ["content/content.js"]
        }
    ]
}

MY ATTEMPTS

I tried wrapping it in a "DOMContentLoaded" event listener like so:

document.addEventListener("DOMContentLoaded", () => {
    console.log(document.querySelector("#title > h1 > yt-formatted-string"));
    console.log(document.getElementById("title"));
});

Honestly, none of the lines was executed after applying this change.

After finding some advice on StackOverflow about the issue with "DOMContentLoaded," I modified the code as follows:

if (document.readyState !== 'loading') init();
else document.addEventListener('DOMContentLoaded', init);

function init() {
    console.log(document.getElementById("title"));
    console.log(document.querySelector("#title > h1 > yt-formatted-string"));
}

Unfortunately, the outcome remained the same:

<div id="title" class="style-scope ytd-watch-metadata">
null

If anyone could shed some light on what might be causing this problem and suggest a solution, it would be highly appreciated.

Answer №1

It is highly likely that the title is not loaded when the page initially loads, but rather fetched later through JavaScript.

One solution is to wait for the selector to be available before performing any actions on it.

function waitForSelector(selector) {
  return new Promise((resolve) => {
    if (document.querySelector(selector)) {
      return resolve(document.querySelector(selector));
    }

    const observer = new MutationObserver((mutations) => {
      if (document.querySelector(selector)) {
        resolve(document.querySelector(selector));
        observer.disconnect();
      }
    });

    observer.observe(document.body, {
      childList: true,
      subtree: true,
    });
  });
}

waitForSelector("#title > h1 > yt-formatted-string").then((el) => console.log(el));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips on showing a personalized message in the Exit Confirmation Popup, not the standard browser alert

How can I display a custom confirmation dialog when a user tries to leave the page after making changes? Currently, my code triggers a confirmation dialog with the default message specific to each browser. window.onbeforeunload = myFunction; funct ...

Acquiring JSON-formatted data through the oracledb npm package in conjunction with Node.js

I am currently working with oracledb npm to request data in JSON format and here is the select block example I am using: const block = 'BEGIN ' + ':response := PK.getData(:param);' + 'END;'; The block is ...

Getting the value of a dropdown list every time it's updated using jQuery

Is it possible to change the image displayed in a select list each time the user makes a selection? Here is my current code: HTML <div id="branches"> <h3>British Columbia Old Age Pensioners' Organization &mdash; Branches</h3&g ...

AngularJS script to dynamically update a table upon selecting an option from the dropdown menu

Just starting out with Angularjs and facing a challenge. I have a table with a "Update" button on the UI and a drop-down option in the 3rd column. The requirement is, upon selecting an option from the drop-down and clicking the "Update" button, the values ...

How can I use JavaScript to find a keyword on a webpage that is not located within an <a> tag or its href attribute?

I'm on a mission to locate a specific keyword within a webpage. Sounds simple, right? Well, here's the tricky part - I need to disregard any instances of this keyword that are nested within an <a> tag. For example: <p>Here is some s ...

Determine the worth of various object attributes and delete them from the list

Currently, my dataset is structured like this: { roof: 'black', door: 'white', windows: 8 }, { roof: 'red', door: 'green', windows: 2 }, { roof: 'black', door: 'green', windows: ...

Is combining Passport.js Google authentication with JWT a logical choice?

I am currently working on integrating Google Login with Passport.js into my MERN stack application. However, I have created this middleware for JWT authentication: const jwt = require("jsonwebtoken"); const config = require("config"); module.exports = a ...

Verifying Initialization Before Destructing jQuery File Upload

I'm currently working with the blueimps jQuery file upload plugin and I need to delete all existing instances before creating new ones. The issue I'm running into is that I receive an error when attempting something like this: $('.upload&ap ...

Can you help me navigate through the router dom v6 to match product IDs from the API?

How do I display a specific product when it's clicked on based on its id from a Django Rest Framework API? I was previously using match from React Router DOM v5, but I'm not sure how to achieve the same functionality since match doesn't exis ...

Challenges Encountered When Trying to Enable AJAX Autocomplete in WordPress Admin Using Select2 Plugin

Looking to add an autocomplete feature in the WordPress admin area using Select2 and AJAX, but struggling with getting the AJAX requests to function properly. PHP Code for Managing AJAX Request: function get_tags_suggestions() { if (!current_user_can(& ...

The unboundStoryFn function returned nothing from the render, indicating that a return statement is likely missing. To render nothing, simply return null

While trying to test a react search component using storybook, I encountered an error called unboundStoryFn. The error message indicates that unboundStoryFn(...): Nothing was returned from render. This usually means a return statement is missing. Or, to re ...

Handling every promise in an array simultaneously

I am facing a problem with my array inside Promise.all. When I try to execute a function for the last iteration of forEach loop, I notice that my count_answers variable is only being set for the last object. This can be seen in the log output; the count_an ...

Having trouble loading my script in the frontend plugin?

After much testing, I have discovered that when I place this code before the get_header() function, the script is successfully loaded. However, when I move it after the get_header() function, it no longer works as intended. It's important to note that ...

The results of the Mongoose aggregation $lookup operation are coming back as an empty array in the 'as' field

Suppose we have two datasets: Order and Seller for a platform similar to Ebay where customers can purchase items from individual sellers. Every Order includes a seller field that indicates the ID of the shop owner. const orderSchema = new mongoose.Schema( ...

Adjust the text color when you select an element

I am trying to figure out how to change the color of my "footertext" to red when I click on either the "left" or "center" containers. Then, I want it to go back to white when I click on any of the containers (left, right, center). This is my current HTML: ...

I am interested in incorporating pinia state management into my Vue 3 project

I'm currently working on implementing pinia state management in Vue 3, but I've encountered the following error: Module not found: Error: Can't resolve 'src/stores/cart' in 'C:\Users\Ali Haider\theme-project&b ...

Searching for variables within files using Node.js and constructing an object from the results

Trying to figure out how to streamline this process. Here's the directory structure I'm working with: src/ modules/ clients/ i18n/ en-US.ts tasks/ i18n/ en-US.ts So, ea ...

Sending a global variable to another controller file in Node.js

I am facing an issue with a global variable called userEmail. The variable is supposed to hold the current user's email value, which is assigned during a post request handling authorization. However, when I try to export this global variable to anothe ...

Tips for avoiding the need to reload a single page application when selecting items in the navigation bar

I am in the process of creating a simple Single Page Application (SPA) which includes a carousel section, an about us section, some forms, and a team section. I have a straightforward question: How can I prevent the page from reloading when clicking on nav ...

React Question: Can I manipulate elements that did not meet the filtering criteria in an array?

Currently, I am developing a React application. Within my project, there is a "Price" popup window featuring a list of prices, which allows users to edit, add, or delete each item within the list. However, I am facing a challenge where I need to update the ...