Ad

Infinite Loop On ComponentWillMount ReactJS

- 1 answer

I'm trying to use ReactJS on Salesforce but the queries are quite problematic

Take a look at this code, trying to make something cool to get all data but the while isn't stop, don't know why, please help me and feel free to ask me anything

componentWillMount(){
    let queryMore = true
    let offSet = 0
    let contents = []
    while(queryMore) {
      makeDeferredProvider()
      let contentObject = SObjectModel.deferredObject('Content')     
      let retrieveOptions = {
        limit: 10,
        where: { 
          Type__c: { eq: 'Image' }
        }
      }      
      offSet > 0 ? retrieveOptions.offset = offSet : ''      
      let contentPromise = contentObject.retrieve(retrieveOptions)
      contentPromise.then( records => {        
        records.forEach( record => {
          let item = {
            'name': record.get('Name'),
            'id': record.get('Id')
          }
          contents.push(item)
        })        
        records.length = 10 ? offSet += 10 : queryMore = false        
      }, error => {
        console.log(error)
      })
    }
    this.setState({
      contents: contents
    })
  }
Ad

Answer

Async React will make this easier in the future, but right now you need to not block rendering while your promise is resolving.

Here's a high-level solution:

  1. Stop using ComponentWillMount. It is being deprecated.
  2. Stop using the while loop. It won't work with your promise. Get it working first then worry about queryMore later. See below.
  3. Add a field in the component state called "loading" and default it to true.
  4. Have a conditional in your render method to load a spinner (or NULL, or something) when "loading" equals true.
  5. In ComponentDidMount*, call your request logic and set state WITHIN the function passed into the .then method after you retrieved all the contents. Make sure to set "loading" to false there.
  6. The conditional in render should then render the contents.

Consider using JSForce (https://jsforce.github.io/) to connect to your object. It already has autoFetch logic included that could replace your queryMore logic.

* Using ComponentDidMount should work but it's probably a bad idea because the component will call out to SF on each render. You should probably use a handler and only call when you don't have the data in state or if you want to refresh for some other reason.

Ad
source: stackoverflow.com
Ad