score:0

i'll take a swing at what you are trying to do here:

<productsquare arrayid="door" />

in order to get to the door array of your productinformation.js file, it would probably be better to have a default export:

/* productinformation.js */
export default {
  door: [/* ...door info*/]
  window: [/* ...window info */],
};

then when you import it, you would:

import products from "./productinformation.js";

for your map function, you would want to use your products import with your props.arrayid:

const productsquares = products[this.props.arrayid].map(...);

in your current code, you are trying to map over the string prop you are passing to your component. what you want is to index the correct product array. you need to either create the default export (written above), or create a map in your render function:

const productmap = { door: door, window: window };
const productsquares = productmap[this.props.arrayid].map(...);

score:1

as alan pointed out, i think the main problem is that when you are referring to this, it is not bound to the main component. for functions that are not part of the standard react component lifecycle (constructor, render, componentdidmount, etc), you must explicitly state that you bind it to the component like this

constructor(props)
{
  super(props)
    this.state = {};

    this.populateproductsquares = this.populateproductsquares.bind(this);
}

that by itself should resolve the immediate problem you are facing.

in addition, i would point out a few things that would make your component a little bit easier to read. for example, having the internal function populateproductsquares start with a capital letter, makes us think that it is a class or component, so i would rename that populateproductsquares (or renderproductsquares in my personal opinion to indicate what it does).

secondly, when you are looping through the products, you don't need to refer to this.props.arrayid[i] since each object is already passed as the product argument in the function (product, i) => when you use map.

and you don't need to assign the result from this.props.arrayid.map(...) to an constant since you are returning it right away.

lastly, since the only thing you are doing in the render method is to call the populateproductsquares function, it doesn't make sense to separate it into a separate function, you could just write it all directly in render (as alan also pointed out). but there are a lot of useful cases where you do want to have it in a separate function, so i think it is important to understand the requirement for binding functions.

to summarise, here is how i might have done it (with a slightly different render function to showcase when you might want to have separate functions).

class productsquare extends component {

  constructor(props)
  {
    super(props)
    this.state = {};

    this.renderproductsquares = this.renderproductsquares.bind(this);
  }

  renderproductsquares()
  {
    return this.props.arrayid.map((product, i) =>
      <div classname = "productsquare" key={i}>
        <img  classname = "mainimage" src ={product.productimage}  alt = "test"/>
        <img  classname = "companyimage" src ={product.companyimage} alt = "test"/>

        <button classname = "addbutton">
          add 
        </button>

        <button classname = "infobutton">
          info
        </button>
      </div>
    );
  }

  render() {
    return (
      <div>
        <h1>here are a bunch of product squares</h1>
        {this.renderproductsquares()}
      </div>
    );
  }
}

export default productsquare;

Related Query

More Query from same tag