1

I am using Localstorage.getItem tocreate a RangeSlider with dynamic defaultSelected Values. I am using the rangeSlider inside a react-modal so I need when the user open the model and use the range slider to create a filter, the state is saved in LocalStorage and when the user open the modal again he get the rangeSlider with the last values he selected in the start and end Here is my code:

constructor(props) {
    super(props);
    this.onPriceValueChange = this.onPriceValueChange.bind(this);   
    localStorage.setItem('priceSlider','');
  }

 onPriceValueChange(value){
    console.log("value:",value)
    console.log("value.start:",value.start)
    localStorage.setItem('priceSlider', JSON.stringify(value));  
    console.log("localStorageonPrice:",localStorage)   
    var obj = JSON.parse(localStorage.getItem('priceSlider'));
    console.log("OBJ:",obj);
    console.log("start:",JSON.parse(localStorage.getItem('priceSlider')).start);
    console.log("end:",JSON.parse(localStorage.getItem('priceSlider')).end);
  }
<Modal
       isOpen={this.props.PriceModalIsOpen}
       onHide={this.handleHide}
       contentLabel="Prix Modal"
 >
 <RangeSlider
    title="40000-80000"
    componentId="priceSlider"
    className="priceRangeSlider"
    dataField="price.keyword"
    range={{
     start: 0,
     end: 100000
    }}
    defaultSelected={{
     start: 20000,
     end: 50000
    }}
    rangeLabels={{
     start: "40",
     end: "80"
   }}                                      
    URLParams={false}
    onValueChange={this.onPriceValueChange}
    />
</Modal>

When I test with a static value for the defaultSelected like this

defaultSelected={{
                start: 20000,
                end: 50000
              }}

enter image description here

The console.log() shows:

enter image description here

but when I want to have the values chosen by the user when he closed the Modal I tied with this:

defaultSelected={{
     start: JSON.parse(localStorage.getItem('priceSlider')).start,
     end: JSON.parse(localStorage.getItem('priceSlider')).end
    }}

But I get this error:

Uncaught SyntaxError: Unexpected end of JSON input
at JSON.parse ()
at ProxyComponent.render (PriceFilterModal.js:91)
at ProxyComponent.hotComponentRender (react-hot-loader.development.js:620)
at ProxyComponent.proxiedRender (react-hot-loader.development.js:635)
at finishClassComponent (react-dom.development.js:13194)
at updateClassComponent (react-dom.development.js:13156)
at beginWork (react-dom.development.js:13825)
at performUnitOfWork (react-dom.development.js:15864)
at workLoop (react-dom.development.js:15903)
at HTMLUnknownElement.callCallback (react-dom.development.js:100)
at Object.invokeGuardedCallbackDev (react-dom.development.js:138)
at invokeGuardedCallback (react-dom.development.js:187)
at replayUnitOfWork (react-dom.development.js:15311)
at renderRoot (react-dom.development.js:15963)
at performWorkOnRoot (react-dom.development.js:16561)
at performWork (react-dom.development.js:16483)
at performSyncWork (react-dom.development.js:16455)
at requestWork (react-dom.development.js:16355)
at scheduleWork$1 (react-dom.development.js:16219)
at scheduleRootUpdate (react-dom.development.js:16786)
at updateContainerAtExpirationTime (react-dom.development.js:16813)
at updateContainer (react-dom.development.js:16840)
at ReactRoot../node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render (react-dom.development.js:17123)
at react-dom.development.js:17263
at unbatchedUpdates (react-dom.development.js:16680)
at legacyRenderSubtreeIntoContainer (react-dom.development.js:17259)
at render (react-dom.development.js:17318)
at renderApp (index.js:11)
at Object. (index.js:19)
at Object../src/index.js (index.js:10)
at webpack_require (bootstrap c230f6f2604486566c3b:678)
at fn (bootstrap c230f6f2604486566c3b:88)
at Object.0 (index.less?83e0:26)
at webpack_require (bootstrap c230f6f2604486566c3b:678)
at bootstrap c230f6f2604486566c3b:724
at bootstrap c230f6f2604486566c3b:724

render @ PriceFilterModal.js:91
hotComponentRender @ react-hot-loader.development.js:620
proxiedRender @ react-hot-loader.development.js:635
finishClassComponent @ react-dom.development.js:13194
updateClassComponent @ react-dom.development.js:13156
beginWork @ react-dom.development.js:13825
performUnitOfWork @ react-dom.development.js:15864
workLoop @ react-dom.development.js:15903 callCallback @ react-dom.development.js:100 invokeGuardedCallbackDev @ react-dom.development.js:138 invokeGuardedCallback @ react-dom.development.js:187 replayUnitOfWork @ react-dom.development.js:15311 renderRoot @ react-dom.development.js:15963 performWorkOnRoot @ react-dom.development.js:16561 performWork @ react-dom.development.js:16483 performSyncWork @ react-dom.development.js:16455 requestWork @ react-dom.development.js:16355 scheduleWork$1 @ react-dom.development.js:16219 scheduleRootUpdate @ react-dom.development.js:16786 updateContainerAtExpirationTime @ react-dom.development.js:16813 updateContainer @ react-dom.development.js:16840 ./node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render @ react-dom.development.js:17123 (anonymous) @ react-dom.development.js:17263 unbatchedUpdates @ react-dom.development.js:16680 legacyRenderSubtreeIntoContainer @ react-dom.development.js:17259 render @ react-dom.development.js:17318 renderApp @ index.js:11 (anonymous) @ index.js:19 ./src/index.js @ index.js:10 webpack_require @ bootstrap c230f6f2604486566c3b:678 fn @ bootstrap c230f6f2604486566c3b:88 0 @ index.less?83e0:26 webpack_require @ bootstrap c230f6f2604486566c3b:678 (anonymous) @ bootstrap c230f6f2604486566c3b:724 (anonymous) @ bootstrap c230f6f2604486566c3b:724 index.js:2178 The above error occurred in the component: in PriceFilterModal (created by Connect(PriceFilterModal)) in Connect(PriceFilterModal) (at DefaultPage.js:36) in div (at DefaultPage.js:31) in DefaultPage (created by Connect(DefaultPage)) in Connect(DefaultPage) (created by Route) in Route (at Root.js:32) in Switch (at Root.js:41) in div (at App.js:33) in div (created by Styled(div)) in Styled(div) (created by URLParamsProvider) in URLParamsProvider (created by Connect(URLParamsProvider)) in Connect(URLParamsProvider) (created by ReactiveBase) in Provider (created by ReactiveBase) in ThemeProvider (created by ReactiveBase) in ReactiveBase (at App.js:29) in div (at App.js:27) in App (at Root.js:27) in Route (at Root.js:25) in Switch (created by Root) in Router (created by ConnectedRouter) in ConnectedRouter (created by Root) in Provider (at Root.js:52) in Root in AppContainer (at index.js:12)

React will try to recreate this component tree from scratch using the error boundary you provided, ReactiveBase.
__stack_frame_overlay_proxy_console__ @ index.js:2178
logCapturedError @ react-dom.development.js:14227
logError @ react-dom.development.js:14266
callback @ react-dom.development.js:14948
callCallback @ react-dom.development.js:10879
commitUpdateQueue @ react-dom.development.js:10923
commitLifeCycles @ react-dom.development.js:14378
commitAllLifeCycles @ react-dom.development.js:15463
callCallback @ react-dom.development.js:100
invokeGuardedCallbackDev @ react-dom.development.js:138
invokeGuardedCallback @ react-dom.development.js:187
commitRoot @ react-dom.development.js:15604
completeRoot @ react-dom.development.js:16619
performWorkOnRoot @ react-dom.development.js:16564
performWork @ react-dom.development.js:16483
performSyncWork @ react-dom.development.js:16455
requestWork @ react-dom.development.js:16355
scheduleWork$1 @ react-dom.development.js:16219
scheduleRootUpdate @ react-dom.development.js:16786
updateContainerAtExpirationTime @ react-dom.development.js:16813
updateContainer @ react-dom.development.js:16840
./node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render @ react-dom.development.js:17123
(anonymous) @ react-dom.development.js:17263
unbatchedUpdates @ react-dom.development.js:16680
legacyRenderSubtreeIntoContainer @ react-dom.development.js:17259
render @ react-dom.development.js:17318
renderApp @ index.js:11
(anonymous) @ index.js:19
./src/index.js @ index.js:10
__webpack_require__ @ bootstrap c230f6f2604486566c3b:678
fn @ bootstrap c230f6f2604486566c3b:88
0 @ index.less?83e0:26
__webpack_require__ @ bootstrap c230f6f2604486566c3b:678
(anonymous) @ bootstrap c230f6f2604486566c3b:724
(anonymous) @ bootstrap c230f6f2604486566c3b:724
index.js:2178 An error has occured. You're using Reactivesearch Version: 2.8.1. If you think this is a problem with Reactivesearch, please try updating to the latest version. If you're already at the latest version, please open an issue at https://github.com/appbaseio/reactivesearch/issues

With Firefox I get:

SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data

enter image description here

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Afef Mokhtari
  • 51
  • 1
  • 9

1 Answers1

1

The below code would work. While storing into localstorage you need to store it with JSON.stringify and while getting the item you need to do JSON.parse

import React from "react"; 
import ReactDOM from "react-dom"; 
import { bindActionCreators } from 'redux'; 
import { connect } from 'react-redux'; 
import * as actions from './redux/actions'; 
import { closePriceModal } from '../filter-bar/redux/actions'; 
import Modal from 'react-modal'; 
import { RangeSlider } from '@appbaseio/reactivesearch'; 

export class PriceFilterModal extends Component { 
static propTypes = { 
  simpleFilter: PropTypes.object.isRequired, 
  actions: PropTypes.object.isRequired, 
  PriceModalIsOpen: PropTypes.bool.isRequired 
}; 

constructor(props) { 
  super(props); 
  localStorage.setItem('priceSlider', ''); 
} 

onPriceValueChange = value => { 
  localStorage.setItem("priceSlider", JSON.stringify(value));
  this.forceUpdate();
} 
handleHide = () => { 
  this.props.actions.closePriceModal(); 
} 

render() { 
  const priceSlider = localStorage.getItem("priceSlider");
  const start = JSON.parse(priceSlider).start;
  const end = JSON.parse(priceSlider).end;
  return ( 
    <div className="simple-filter-price-filter-modal"> 
      <Modal 
      isOpen={this.props.PriceModalIsOpen} 
      onHide={this.handleHide} 
      contentLabel="Prix Modal" 
      > 
          <div className="multiList"> 
            <RangeSlider
                title="40000-80000"
                componentId="priceSlider"
                className="priceRangeSlider"
                dataField="price.keyword"
                range={{
                  start: 0,
                  end: 100000
                }}
                defaultSelected={{
                  start: start,
                  end: end
                }}
                rangeLabels={{
                  start: "40000",
                  end: "80000"
                }}
                URLParams={false}
                onValueChange={this.onPriceValueChange}
              />
          </div> 
        <button type="button" onClick={this.handleHide} className="btn btn-circle"></button> 
      </Modal> 
    </div > 
  ); 
} 
} 
function mapStateToProps(state) { 
  return { 
    simpleFilter: state.simpleFilter, 
  }; 
} 

/* istanbul ignore next */ 
function mapDispatchToProps(dispatch) { 
  return { 
    actions: bindActionCreators({ ...actions, closePriceModal }, dispatch) 
  }; 
} 

export default connect(mapStateToProps, mapDispatchToProps)(PriceFilterModal);

Please find working demo here

Hemadri Dasari
  • 32,666
  • 37
  • 119
  • 162
  • But I did it here onPriceValueChange(value){ localStorage.setItem('priceSlider', JSON.stringify(value)); – Afef Mokhtari Oct 01 '18 at 15:30
  • I tried it now but I am getting: index.js:2178 Warning: Failed prop type: The prop `defaultSelected.start` is marked as required in `RangeSlider`, but its value is `undefined`. in RangeSlider (created by Connect(RangeSlider)) . Also the slider is not activatedanymore to choose any values! actually it return undefined in the consoel. – Afef Mokhtari Oct 01 '18 at 15:37
  • It's not an error its a warning. You need to pass as an object rather then using {{}} double curly brackets. I updated my answer please give a try – Hemadri Dasari Oct 01 '18 at 15:58
  • I got an error: Unexpected token, expected } here start: JSON.stringify(localStorage.getItem('priceSlider')).start, – Afef Mokhtari Oct 01 '18 at 16:02
  • Can you do console.log(localStorage.getItem('priceSlider')) and let me know what it prints – Hemadri Dasari Oct 01 '18 at 16:04
  • it gives: {"start":20000,"end":50000} – Afef Mokhtari Oct 01 '18 at 16:06
  • Can you try defaultSelected = {{ start: localStorage.getItem('priceSlider').start, end: localStorage.getItem('priceSlider').end }} – Hemadri Dasari Oct 01 '18 at 16:09
  • value: {start: NaN, end: NaN} PriceFilterModal.js:28 value.start: NaN PriceFilterModal.js:30 localStorageonPrice: Storage {carsbrand: "", carsmodel: "", priceSlider: "{"start":null,"end":null}", length: 3} PriceFilterModal.js:34 OBJ: {start: null, end: null} PriceFilterModal.js:35 start: null PriceFilterModal.js:36 end: null and it make an Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops. – Afef Mokhtari Oct 01 '18 at 16:15
  • and the console.log(localStorage.getItem('priceSlider')); gives {"start":null,"end":null} – Afef Mokhtari Oct 01 '18 at 16:16
  • @AfefMokhtari I found the issue. Take the latest code from my answer and try from your end – Hemadri Dasari Oct 01 '18 at 18:26
  • the working solution generate an error in this ligne const start = JSON.parse(priceSlider).start; which is Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse () – Afef Mokhtari Oct 02 '18 at 09:09
  • Please check the working demo linked in my answer. Dono why it’s breaking in your machine – Hemadri Dasari Oct 02 '18 at 10:29