API integration with React.js

hi
I am trying to integrate API with our application using React.js.
There is below error on using “new window.SDVApp.ParametricViewer(settings);”
The error looks like cloning objet problem with JSON in javascript
Is there anyone integrating API with React.js? how to solve this problem?

=== error ===
Uncaught TypeError: Converting circular structure to JSON
at JSON.stringify ()
at GlobalUtils$$module$src$shared$util$GlobalUtils.deepCopy (GlobalUtils.js:259)
at module$src$app$ViewerApp.default.module$src$shared$mixins$SettingsMixin.default (SettingsMixin.js:64)
at new module$src$app$ViewerApp.default (ViewerApp.js:80)
at new ParametricViewer$$module$build$package.ParametricViewer (package.js:371)

=====javascript code in React component=====
const settings = {
container: window.document.getElementById(‘sdv-container’),
ticket: ‘my_ticket’,
};
this.api = new window.SDVApp.ParametricViewer(settings);

===== error occurs at =====
this.deepCopy = function(o, assign) {
if (o === undefined) return;
if (!assign) {
// simple case, copy everything, potentially loosing objects which can’t be stringified
return JSON.parse( JSON.stringify(o,that.deepCopyReplacer), that.deepCopyReviver );
}

===== variable o in the above =====
o:
anchorElements: true
apiversion: “2”
authorization: “”
blurSceneWhenBusy: true
brandedMode: true
build_branch: “master”
build_commit: “3dc67e2fc3b4a29c26299eb23243ab3351858dd6”
build_date: “2019-02-01T17:50:34.944Z”
build_version: “2.5.0”
busyGraphic: null
commPluginRuntimeId: “CommPlugin_1”
container: div#sdv-container
containerControls: null
containerSettings: null
createButtons: true
deferGeometryLoading: false
domElementIdPrefix: “sdv-container”
editMode: false
exportModal: true
exposeViewer: false
iframeDebugging: false
loggingLevel: -1
messageLoggingLevel: -1
modelViewUrl: “”
showBusySpinner: true
showControlsButton: true
showControlsInitial: false
showFullscreenButton: true
showInitialSpinner: true
showSceneMode: 2
showSettingsButton: true
showSettingsInitial: false
showZoomButton: true
ticket: “my_ticket”
viewportOverlays: true
zoomButtonResetsCamera: false

It seems there are some specifics related to React which we would need to change in the viewer constructor to make this work. Please try this for now:

  1. Initially set the container property to an empty array, then call the viewer constructor.
  2. Use the viewport API to create a viewport: https://viewer.shapediver.com/v2/2.5.0/doc/module-ApiInterfaceV2-ApiViewportsInterface.html

Looking forward to your feedback.

I changed my code to

const settings = {
container: [ ],
ticket: ‘my_ticket’,
};
this.api = new window.SDVApp.ParametricViewer(settings);

=== error ===
package.js:283 Uncaught TypeError: Cannot read property ‘parentElement’ of undefined
at new ParametricViewer$$module$build$package.ParametricViewer (package.js:283)

not working because according to your link about viewport api, viewport can be created by api instance. but api construction is failed because above code.

I will review and get back to you. The viewer had not been used yet with react, but it shouldn’t be a problem.

There was a bug related to passing an empty container array to the constructor. This has been fixed in version 2.6.0, please give it a try: https://viewer.shapediver.com/v2/2.6.0/doc/index.html

@tiredtire could you get you react application to work with our viewer?

Hello @snabela I am also trying to integrate with react and getting this same error and am using version 2.6.0.

if there is no container everything goes smoothly and the request actually returns data from the api but when there is a container it throws this error I have been able to see where it is coming from through the console its when you try to stringfy a json in a globalUtils.js file. I can share more details as required because we really need to integrate this in our app in the shortest time.

Regards

Hi @ovuobasampson, the latest version of our viewer out there is 2.14.0, you can always find the latest version by visiting www.shapediver.com/api, which will take you to the release notes and documentation of the latest released viewer.
Let me know whether the problem still happens.

Hello @snabela thanks for pointing me that direction, I have made the necessary changes to adapt that but am currently having a cors error as am trying to use the plugin, I used the defer attribute that was recommended in the docs but was still getting the error I also used the crossorigin attribute which was what I used for the formal version of the plugin to avoid the error and I was still getting it. I am very open to any suggestions you might have. The domain making the request actually has ssl installed too.

Thanks as I await your response.

Regards

Please post a screenshot of the CORS error from the browser console, or copy&paste it here.

Hello,

sorry I later cleared the cors error. But it came back to this.

backend.js:1 TypeError: Converting circular structure to JSON
–> starting at object with constructor ‘HTMLDivElement’
| property ‘__reactInternalInstance$7bfqfp2e6mm’ -> object with constructor ‘Hr’
— property ‘stateNode’ closes the circle
at JSON.stringify ()
at GlobalUtils$$module$src$shared$util$GlobalUtils.deepCopy (GlobalUtils.js:260)
at module$src$app$ViewerApp.default.module$src$shared$mixins$SettingsMixin.default (SettingsMixin.js:64)
at new module$src$app$ViewerApp.default (ViewerApp.js:80)
at new ParametricViewer$$module$build$package.ParametricViewer (package.js:396)
at t.value (Model.js:28)
at qo (react-dom.production.min.js:4978)
at Ho (react-dom.production.min.js:5123)
at react-dom.production.min.js:5975
at Object.t.unstable_runWithPriority (scheduler.production.min.js:274)

GlobalUtils.js:260 Uncaught (in promise) TypeError: Converting circular structure to JSON
–> starting at object with constructor ‘HTMLDivElement’
| property ‘__reactInternalInstance$7bfqfp2e6mm’ -> object with constructor ‘Hr’
— property ‘stateNode’ closes the circle
at JSON.stringify ()
at GlobalUtils$$module$src$shared$util$GlobalUtils.deepCopy (GlobalUtils.js:260)
at module$src$app$ViewerApp.default.module$src$shared$mixins$SettingsMixin.default (SettingsMixin.js:64)
at new module$src$app$ViewerApp.default (ViewerApp.js:80)
at new ParametricViewer$$module$build$package.ParametricViewer (package.js:396)
at t.value (Model.js:28)
at qo (react-dom.production.min.js:4978)
at Ho (react-dom.production.min.js:5123)
at react-dom.production.min.js:5975
at Object.t.unstable_runWithPriority (scheduler.production.min.js:274)

Here is the code for the model.js

let _container = this.refs.containersdv;
const settings = {
container: _container,
ticket: ‘TICKET_TOKEN’,
modelViewUrl : ‘eu-central-1’
};
this.api = new window.SDVApp.ParametricViewer(settings);

It seems that whatever you are passing as property container causes the problem. What kind of object are you passing?
Expected is an Element object, e.g. as returned from document.getElementById.
This is what our viewer uses in case you don’t pass a container:

document.getElementById('sdv-container-viewport')

Ok, Thanks for your response. what am passing is a div in the page that has a a ref of ‘containersdv’ which is what am referencing in this line

let _container = this.refs.containersdv;

But then to experiment I removed the entire container and since it defaults to an element with an id of ‘sdv-container-viewport’ I created a div with that id. But the error was still the same. The only way am not getting the error is if I use an empty container this way

const settings = {
container:  [ ],
ticket: ‘TICKET_TOKEN’,
modelViewUrl : ‘eu-central-1’
};

But I need a container for it to render, so I cant use that.

Thanks very much as I await your response

Many thanks for your reply. It’s not clear to me yet what’s going on. Could you post a minimal code example which allows to reproduce the problem?

Sure here it is I just created a component in react and added the code;

import React, { Component } from "react";

  class Model extends Component {


      componentDidMount() {
        // container for the viewer, typically this is a div
        let _container = this.refs.containersdv;
    // viewer settings
        const settings = {
          container:   _container,
          ticket: 'TICKET_TOKEN',
          modelViewUrl : 'eu-central-1'
        };
        this.api = new window.SDVApp.ParametricViewer(settings);
}
       

      render() {
       

        return (
          <div>
             <div ref="containersdv"></div>
          </div>
        );
      }
    }

    export default Model;

Many thanks. It seems React adds some properties to the div which cause the problem. We made some changes in the staging version of our viewer. Please give it a try using the following files:

In case this works it will become part of the upcoming release 2.15.0

Ah really glad you have been able to identify the problem. Thanks for this. I just switched to the staging version at the moment and gave it another try but it seems to still need a few changes as amstill getting the error in the console. I cleared the cache and confirmed it was linked to the staging file to make sure but it was the same error it returned.

Thanks very much as I await your response

We will create a minimal example which shows how to embed the viewer into a React App. Please be patient, we might be able to get it done this week, but this is not guaranteed.

Thank you very much for this really appreciate that. No problem, I will be waiting on you guys.

Please check out this example to see how it works: https://codepen.io/ShapeDiver/pen/oNvoBxb?editors=1010
For now this works only using the development version of our viewer, will let you know as soon as this becomes part of a release.