0

So I'm new to javascript and am having problems targeting the method I would like to target in my constructor

class Stock_List {
  constructor() {
    // fetching the json file (async)
    fetch('../stocks.json')
      .then(function (resp) {
        return resp.json();
      })
      .then(function (data) {
        let stock_info_arr = data.stock_info;
        for (const stock of stock_info_arr) {
          console.log(stock);
          this.add_stock(stock);
        }
      });
  }

I am having problems where I am trying to call the add_stock function which is in the class as a method but the this key word seems to be targeting the data of what the json is returning.In reality I want the this tag to target the Stock_list object. Does anyone know of a solution where this can be fixed. Thanks!

this is what the full class looks like

class Stock_List {
  constructor() {
    // fetching the json file (async)
    fetch('../stocks.json')
      .then(function (resp) {
        return resp.json();
      })
      .then(function (data) {
        let stock_info_arr = data.stock_info;
        for (const stock of stock_info_arr) {
          console.log(stock);
          this.add_stock(stock);
        }
      });
  }

  add_stock(jsObject) {
    let big_container = document.querySelector('.background');
    // this statement fixes the background once a stock is added
    big_container.style.position = 'sticky';
    let stock_container = document.createElement('div');
    stock_container.className = 'stock_container';
    stock_container.id = jsObject['stock_ticker'];
    // stock header being built
    stock_container.innerHTML = `
    <div class="stock_header">
      <h2 class="stock_ticker">${jsObject['stock_ticker']}</h2>
      <h2 class="price">${jsObject['price']}</h2>
      <h2 class="percent_change">${jsObject['percent_change']}</h2>
      <button>
        <div class="line"></div>
      </button>
    </div>`;
    // articles being built
    for (let i = 0; i < jsObject['headers'].length; i++) {
      stock_container.innerHTML += `
      <div class="articles">
        <h3>${jsObject['headers'][i]}</h3>
        <p>
          ${jsObject['articles'][i]}
        </p>`;
    }
    //closing off the div of the stock container
    stock_container.innerHTML += `
    </div>`;

    big_container.appendChild(stock_container);
  }
}
Kninja99
  • 13
  • 5
  • try `console.log(this)`, see what it set to. – vanowm Aug 10 '21 at 05:27
  • Does this answer your question? [How to access the correct \`this\` inside a callback](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – Harsh Saini Aug 10 '21 at 05:29

1 Answers1

0

this can be confusing but it's determined by how a function is called. Call an async function from your constructor instead.

class Stock_List {

  constructor() {
    this.getData();
  }
 
  async getData() {
    const response = await fetch('../stocks.json');
    const data = await response.json();
    for (const stock of data.stock_info) {
      this.add_stock(stock);
    }
  }
 
}
Andy
  • 61,948
  • 13
  • 68
  • 95
  • 1
    solution worked perfect, thank you so much! this is a bit confusing especially since promises are a new concept to me and so is await and async. Yet you explained it very clear. Thanks again – Kninja99 Aug 10 '21 at 05:44