appbaseio / reactivesearch

Search UI components for React and Vue
https://opensource.appbase.io/reactivesearch
Apache License 2.0
4.89k stars 471 forks source link

How to call button onClick() event in onData() function ??? #103

Closed ashwini987 closed 6 years ago

ashwini987 commented 6 years ago

I want to call onClick event on button click and button is inside the onData() function. Here it is my code,

    ` class HelloWorld extends Component {
      cart(res){
          console.log("res",res);
     }

onData(res) {
    const result = {
        image :  "http://image.promoworld.ca/migration-api-hidden-new/web/images/" + res.default_image,
        desc : (
            <div className="icon">
                    <button onClick={cart(res.sku) }>
                        <span className="glyphicon glyphicon-shopping-cart"></span>
                    </button>

                <div className="product-info">
                    <div className="pull-right product-price">{res.min_price}</div>
                    <span className="product-title">{res.product_name}</span>
                </div>
            </div>
        )
    };
console.log(res.sku);
    return result;
}
    render() {
    return ......
     }
  }`

It show me error like 'cart' is not a function and not defined. How to call function??

metagrover commented 6 years ago

Hi @ashwini987

This is pretty simple. In the given code-snippet, you're trying to call cart() in the context of your component (ResultList/ResultCart) which doesn't have access to the HelloWorld's context.

For such cases, you need to first bind() the method with HelloWorld's context and then use it in your component.

class HelloWorld extends Component {
    constructor(props) {
        super(props);

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

    cart() { ... }

    onData(res) {
    const result = {
        image :  "...",
        desc : (
            <div className="icon">
                    <button onClick={() => this.cart(res.sku)}>
                        <span className="glyphicon glyphicon-shopping-cart"></span>
                    </button>
                                        // more code
            </div>
        )
    };
    return result;
    }
}
ashwini987 commented 6 years ago

Here you create a constructor so it called only one time i want to call this 'cart( )' function every product is clicked and it called.

Here it is my whole code:-

 `import React, { Component } from 'react';
   import ReactDom from 'react-dom';
   import {
              ReactiveBase,
             CategorySearch,
              RatingsFilter,
              NestedList,
              ResultCard,
              RangeSlider,
              MultiList,
             TagCloud
      } from '@appbaseio/reactivesearch';

     let URL = "XXXXXXXXXXXXXXXXXXXXXXXX";
     let apiUsername = "XXXXXXXXX";
     let apiPassword = "XXXXXXXXXXXXXXXXXXXX"
     var auth = apiUsername + ":" + apiPassword
     var val;
     var defaultSelected;

      require("./index.scss");

      class HelloWorld extends Component {

 constructor(props) {
    super(props);

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

rangeFunction(value) {
    console.log('value', value)
  return new Promise((resolve, reject) => {
    resolve()
  })
}
 cart(res){
console.log("res",res);
}

onData(res) {
    const result = {
        image :  "http://image.promoworld.ca/migration-api-hidden-new/web/images/" + res.default_image,
        desc : (
            <div className="icon">

                    <button onClick={ () => this.cart(res.sku) }>
                        <span className="glyphicon glyphicon-shopping-cart"></span>
                    </button>
                    <button onClick={() => {console.log("wishlist res",res) } }>
                        <span className="glyphicon glyphicon-heart"></span>
                    </button>
                    <button onClick="compare()">
                        <span className="glyphicon glyphicon-retweet"></span>
                    </button>

                <div className="product-info">
                    <div className="pull-right product-price">{res.min_price}</div>
                    <span className="product-title">{res.product_name}</span>
                </div>
            </div>
        )
    };
console.log(res.sku);
    return result;
}
render() {
    return (
        <div>
            <ReactiveBase
            url= {URL}
            app="XXXXX"
            credentials= {auth}
            theme="rbc-orange"
            >
                <div className="row reverse-labels">

                    <nav className="row">
                        <div className="col s3">
                            <a href="#!" className="brand-logo">closeout promo</a>
                        </div>
                        <div className="col s9">
                            <CategorySearch
                                componentId="SearchSensor"
                                appbaseField="product_name"
                                categoryField="categories.raw"
                                placeholder="Search"
                                autocomplete={false}
                                URLParams={true}
                                onValueChange = {
                                function(value) {
                                  console.log("current value:", value)
                                }
                              }
                            />
                        </div>
                    </nav>

                    <div className="col s3">
                    <div className="">
                        <div className="" id="Category">
                            <MultiList
                                componentId="CategoryMultilistSensor"
                                appbaseField="categories.raw"
                                title="Category"
                                size={1000}
                                sortBy="asc"
                                showCount={true}
                                showSearch={false}
                                searchPlaceholder="Search Category"
                                initialLoader="Loading categorys list.."
                                react={{
                                    and: ["PriceRangeSensor", "SearchSensor", "ColorsMultilistSensor"]
                                }}

                            />
                        </div>

                        <div className="" id="PriceRange">
                            <RangeSlider
                                componentId="PriceRangeSensor"
                                appbaseField="min_price"
                                title="Price"
                                range={{
                                        start: 0,
                                        end: 100
                                    }}
                                stepValue={3}
                                showHistogram={false}
                                initialLoader="Rendering the histogram.."
                                react={{
                                    and: ["CategoryMultilistSensor", "SearchSensor", "ColorsMultilistSensor"]
                                }}

                            />
                        </div>
                        <div className="" id="ColorsMultilist">
                            <MultiList
                                componentId="ColorsMultilistSensor"
                                appbaseField="attributes.colors.raw"
                                title="Colors"
                                size={1000}
                                sortBy="asc"
                                showCount={true}
                                showSearch={false}
                                searchPlaceholder="Search Colors"
                                initialLoader="Loading Colors list.."
                                react={{
                                    and: ["SearchSensor", "CategoryMultilistSensor", "PriceRangeSensor"]
                                }}
                            />
                        </div>

                    </div>
                    </div>
                    <div className="col s9" id="ResultCard">
                        <ResultCard
                            appbaseField="title"
                            size={15}
                            onData={this.onData}
                            pagination={true}
                            sortOptions={[
                                    {
                                            label: "Lowest Price First",
                                            appbaseField: "min_price",
                                            sortBy: "asc"
                                    },
                                    {
                                            label: "Highest Price First",
                                            appbaseField: "min_price",
                                            sortBy: "desc"
                                    }
                            ]}
                            react={{
                                    and: ["SearchSensor","PriceRangeSensor","CategoryMultilistSensor","ColorsMultilistSensor"]
                            }}

                        />
                    </div>
                </div>
            </ReactiveBase>
        </div>
    );
}
  }

    HelloWorld.defaultProps = {
mapping: {
    title : "product_name",
    category: "categories.raw",
}
  };

 ReactDom.render(<HelloWorld />, document.getElementById('app'));`

Now I am attached picture screenshot from 2017-10-17 17-21-06

Where product is display in Resultcard, there is one button for 'Add to Cart' and it call the function 'cart( )'. But here it is throw me error, "_this2.cart" is not a function.

metagrover commented 6 years ago

To fix this, update your constructor code to look like this:

constructor(props) {
    super(props);

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

This will ensure that the onData() method will be called with HelloWorld's context, and hence your this.cart() will be called correctly.

ashwini987 commented 6 years ago

This give same result as i done before create the issue. as i click on add-to-cart button on 1st resultcard product it give me sku of that product but i click on add-to-cart button for differnt product it not give sku of that product. this my issue as i click on any products add-to-cart button at that time "onClick()" function call nd give me the sku for that clicked products.

metagrover commented 6 years ago

Not sure what you're trying to say but check this code snippet: https://codepen.io/metagrover/pen/PJxVMB?editors=0010

I've added Click here to log price link in the ResultCard's markup. It logs the respective price of the housing-property. Hope this helps.