1

I am having problems loading JSON into a react component that will render a survey powered by SurveyJS.

Everything works just fine when I define the survey data as a object in the component file. Does not work when I get the JSON from API (AWS-Lambda) and put it into state.

I've console log both - and I cannot detect any difference between the values in state and the values defined inline -- a conundrum! The SurveyJS error message is There is no visible page or question in the survey.

What am I doing wrong with handling state or JSON object ?

import React, { Component } from "react";
import * as Survey from "survey-react";
import "survey-react/survey.css";
import "survey-react/modern.css"
import { API } from "aws-amplify";

export default class SimpleSurvey extends Component {
    constructor(props) {
        super(props);
        this.state = {
            survey: {},
          };      
      }

    async componentDidMount() {

        try {
            let querystring = {'queryStringParameters':{'surveyId':this.props.surveyId}}
            const surveyjson = await this.getSurvey(querystring);
            this.setState({ survey: surveyjson});
        } catch (e) {
          alert(e);
        }
      }

      getSurvey(querystring) {
        return  API.get("survey", "/survey", querystring);
        }

simpleone = {"pages": [{"name": "page1","elements": [{"type": "text","name": "question1"}]}]}

 render() {
    console.log('simpleone object', this.simpleone)
    console.log('state object', this.state.survey)
    console.log('both obj the same?', this.simpleone === this.state.survey)
    console.log('simpleone string', JSON.stringify(this.simpleone))
    console.log('state string', JSON.stringify(this.state.survey))
    console.log('both string the same?', JSON.stringify(this.simpleone)===JSON.stringify(this.state.survey))

    // issue:  model works if use this.simpleone defined above; does not work if use this.state.survey set from API
    var model = new Survey.Model(this.simpleone);
    return (<Survey.Survey model={model}/>);
  }

}

And here is the console.log with the simpleone object and state...

console log

azro
  • 53,056
  • 7
  • 34
  • 70
English
  • 11
  • 3
  • Welcome to StackOverflow! :) Could it be the case because you're not awaiting on the getSurvey function? Seems to me that it's possibly an asynchronous operation. – saglamcem Dec 10 '19 at 22:05
  • Thanks - I await the getSurvey when component mounts. I'd have thought that when state is updated, then everything would re-render. But when I change the code to `var model = new Survey.Model(this.state.survey)` it seems like it does not – English Dec 10 '19 at 23:24

1 Answers1

0

yes @saglamcem - the problem was not waiting for async before trying to create the model

Changed render function to wait for state to get populated with the JSON from the API before calling new Survey.Model


export default class SimpleSurvey extends Component {
    constructor(props) {
        super(props);

        this.state = {
            survey: null,
          };      
      }

    async componentDidMount() {

        try {
            let querystring = {'queryStringParameters':{'surveyId':this.props.surveyId}}
            const surveyjson = await this.getSurvey(querystring);
            this.setState({ survey: surveyjson});
        } catch (e) {
          alert(e);
        }
      }

      getSurvey(querystring) {
        return  API.get("survey", "/survey", querystring);
        }

      getModel(json){
        var model = new Survey.Model(json);
        return (<Survey.Survey model={model} onComplete={this.onComplete}/>);
      }

      onComplete(survey, options) {
        console.log("Survey results: " + JSON.stringify(survey.data));
       }

 render() {
   return(
    <div>
    {this.state.survey ? this.getModel(this.state.survey) : null}
    </div>
   )
  }
} 
English
  • 11
  • 3
  • Yes - that works. Problem was in calling getModel before the async process completed. Previously I assumed that when state was updated it would call the getModel again with new values, but apparently that wasnt the case. – English Dec 11 '19 at 17:49