0

I want to parse a full json string:

generateComponents(){
    const component = JSON.parse(this.state.content);
    console.log(component.name);
}

This is the JSON in "this.state.component": Already changed the json structure at least 3 times. If i convert the json string with stringfy e parse again, the react return the object, but i cant access anything from it for example: if i try to access the "name" attribute, the react returns that this attribute dont exist.

The json stored in state: (this.state.content)

{
"name": "cliente",
"components": [
    {
        "component": "field",
        "label": "Nome",
        "description": "Primeiro nome do cliente.",
        "type": "string",
        "_rid": "nome"
    }
]

}

React shows to me this error:

Error: A cross-origin error was thrown. React doesn't have access to the actual error object in development.

--

Uncaught SyntaxError: Unexpected end of JSON input
at JSON.parse (<anonymous>)
at ModulePocPage.generateComponents (index.js:16)
at ModulePocPage.render (index.js:32)
at finishClassComponent (react-dom.development.js:17160)
at updateClassComponent (react-dom.development.js:17110)
at beginWork (react-dom.development.js:18620)
at HTMLUnknownElement.callCallback (react-dom.development.js:188)
at Object.invokeGuardedCallbackDev (react-dom.development.js:237)
at invokeGuardedCallback (react-dom.development.js:292)
at beginWork$1 (react-dom.development.js:23203)
at performUnitOfWork (react-dom.development.js:22157)
at workLoopSync (react-dom.development.js:22130)
at performSyncWorkOnRoot (react-dom.development.js:21756)
at scheduleUpdateOnFiber (react-dom.development.js:21188)
at updateContainer (react-dom.development.js:24373)
at react-dom.development.js:24758
at unbatchedUpdates (react-dom.development.js:21903)
at legacyRenderSubtreeIntoContainer (react-dom.development.js:24757)
at Object.render (react-dom.development.js:24840)
at Module../src/index.js (index.js:7)
at __webpack_require__ (bootstrap:784)
at fn (bootstrap:150)
at Object.1 (serviceWorker.js:141)
at __webpack_require__ (bootstrap:784)
at checkDeferredModules (bootstrap:45)
at Array.webpackJsonpCallback [as push] (bootstrap:32)
at main.chunk.js:1
generateComponents @ index.js:16
render @ index.js:32
finishClassComponent @ react-dom.development.js:17160
updateClassComponent @ react-dom.development.js:17110
beginWork @ react-dom.development.js:18620
callCallback @ react-dom.development.js:188
invokeGuardedCallbackDev @ react-dom.development.js:237
invokeGuardedCallback @ react-dom.development.js:292
beginWork$1 @ react-dom.development.js:23203
performUnitOfWork @ react-dom.development.js:22157
workLoopSync @ react-dom.development.js:22130
performSyncWorkOnRoot @ react-dom.development.js:21756
scheduleUpdateOnFiber @ react-dom.development.js:21188
updateContainer @ react-dom.development.js:24373
(anonymous) @ react-dom.development.js:24758
unbatchedUpdates @ react-dom.development.js:21903
legacyRenderSubtreeIntoContainer @ react-dom.development.js:24757
render @ react-dom.development.js:24840
./src/index.js @ index.js:7
__webpack_require__ @ bootstrap:784
fn @ bootstrap:150
1 @ serviceWorker.js:141
__webpack_require__ @ bootstrap:784
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1
index.js:1 The above error occurred in the <ModulePocPage> component:
in ModulePocPage (at App.js:8)
in div (at App.js:7)
in App (at src/index.js:9)
in StrictMode (at src/index.js:8)
Consider adding an error boundary to your tree to customize error handling behavior.
Visit to learn more about error boundaries.
console.<computed> @ index.js:1
logCapturedError @ react-dom.development.js:19527
logError @ react-dom.development.js:19564
update.callback @ react-dom.development.js:20708
callCallback @ react-dom.development.js:12490
commitUpdateQueue @ react-dom.development.js:12511
commitLifeCycles @ react-dom.development.js:19883
commitLayoutEffects @ react-dom.development.js:22803
callCallback @ react-dom.development.js:188
invokeGuardedCallbackDev @ react-dom.development.js:237
invokeGuardedCallback @ react-dom.development.js:292
commitRootImpl @ react-dom.development.js:22541
unstable_runWithPriority @ scheduler.development.js:653
runWithPriority$1 @ react-dom.development.js:11039
commitRoot @ react-dom.development.js:22381
finishSyncRender @ react-dom.development.js:21807
performSyncWorkOnRoot @ react-dom.development.js:21793
scheduleUpdateOnFiber @ react-dom.development.js:21188
updateContainer @ react-dom.development.js:24373
(anonymous) @ react-dom.development.js:24758
unbatchedUpdates @ react-dom.development.js:21903
legacyRenderSubtreeIntoContainer @ react-dom.development.js:24757
render @ react-dom.development.js:24840
./src/index.js @ index.js:7
__webpack_require__ @ bootstrap:784
fn @ bootstrap:150
1 @ serviceWorker.js:141
__webpack_require__ @ bootstrap:784
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1
react-dom.development.js:248 Uncaught Error: A cross-origin error was thrown. React doesn't have `enter code here`access to the actual error object in development. for more information.
at Object.invokeGuardedCallbackDev (react-dom.development.js:248)
at invokeGuardedCallback (react-dom.development.js:292)
at beginWork$1 (react-dom.development.js:23203)
at performUnitOfWork (react-dom.development.js:22157)
at workLoopSync (react-dom.development.js:22130)
at performSyncWorkOnRoot (react-dom.development.js:21756)
at scheduleUpdateOnFiber (react-dom.development.js:21188)
at updateContainer (react-dom.development.js:24373)
at react-dom.development.js:24758
at unbatchedUpdates (react-dom.development.js:21903)
at legacyRenderSubtreeIntoContainer (react-dom.development.js:24757)
at Object.render (react-dom.development.js:24840)
at Module../src/index.js (index.js:7)
at __webpack_require__ (bootstrap:784)
at fn (bootstrap:150)
at Object.1 (serviceWorker.js:141)
at __webpack_require__ (bootstrap:784)
at checkDeferredModules (bootstrap:45)
at Array.webpackJsonpCallback [as push] (bootstrap:32)
at main.chunk.js:1

Full Component:

import React from 'react';
import styled from 'styled-components';


export default class ModulePocPage extends React.Component{
constructor(props){
    super(props);
}

state = {
    content: ''
}

generateComponents(){
    const component = JSON.parse(this.state.content);
    console.log(component.name);
}

render(){

    const PreviewField = styled.div`
        width: 100%;
        height: 400px;
        background: red;
    `

    return(
        <div>
            <textarea className="scriptField" onChange={(event) => this.setState({ content: event.target.value })}></textarea>
            <PreviewField>
                {this.generateComponents()}
            </PreviewField>
        </div>
    )
    }
}
Geeh Oliveira
  • 103
  • 2
  • 8
  • Are you developing this locally? I only had those kinds of errors in online IDEs like codesandbox. It does say that you had `Unexpected end of JSON input` passed to the JSON.parse so it's an issue with the JSON. What exactly is the value of `this.state.content`? – paolostyle May 16 '20 at 19:56
  • The exact json in the question, i dont know what is wrong. – Geeh Oliveira May 16 '20 at 20:12
  • Can you post the whole component code? – paolostyle May 16 '20 at 20:16
  • You can check now, i change the post – Geeh Oliveira May 16 '20 at 20:49
  • @GeehOliveira Where is the JSON actually coming from? The code you have given doesn't imply it is anywhere... `this.state.content` is a string at all times and will throw the error you posted because it can't be parsed JSON (as it's just an empty string, or a string with alphanumeric characters). – Shakespeare May 16 '20 at 21:04
  • The json comes from a textarea field, i can write in the textarea and then i get the whole json string from there – Geeh Oliveira May 16 '20 at 21:10
  • (1) what's the full stack for the cross-origin error message? it's possible that it's an unrelated problem. (2) does `console.log(typeof this.state.content);` give you what you expect? (3) what appears in your browser tools when you set a breakpoint right before parsing `this.state.content`? – Dan O May 16 '20 at 23:43

2 Answers2

0

The fact that the JSON content is coming from a textarea is the reason why. Try running JSON.parse('') in console, you'll get the same error. Your generateComponents() method is called with the initial value of this.state.content, which is an empty string, which is not valid JSON. To fix it, you should wrap it in a try/catch:

generateComponents() {
    try {
      const component = JSON.parse(this.state.content);
      // ...do something with it and return a React element
    } catch (err) {
      return 'Invalid JSON';
    }
  }
paolostyle
  • 1,849
  • 14
  • 17
-1

So I think it has an issue accessing this within your function because you haven't bound the function to this so it's losing scope possibly. In your constructor, add this.generateComponents = this.generateComponents.bind(this);

I think you're seeing a similar issue to this question where the code is losing scope of your current state because it's being called incorrectly. That should give it the scope it needs to parse your JSON properly.

Hope that helps

DrMoney
  • 355
  • 2
  • 8
  • My json came from a textarea field in the page, doesnt make sense. – Geeh Oliveira May 16 '20 at 21:02
  • Ok that's weird, I had to google around and actually found a similar topic: https://stackoverflow.com/questions/48611310/uncaught-error-a-cross-origin-error-was-thrown-react-doesnt-have-access-to-th If you console.log your `this.state.content` before you parse it, does it come back with the right value? – DrMoney May 16 '20 at 21:12
  • Yes, comes the string json, the problem really is the parse method – Geeh Oliveira May 16 '20 at 21:31
  • Ok, so after reading the link I sent you and looking over your code, I think you need to bind your function to `this`, I'll update my answer to show it better – DrMoney May 16 '20 at 21:51
  • a component's `render` method (and therefore any other `this.foo` methods invoked by it) gets called with `this` set to what you'd expect. binding `generateComponents` will do nothing here. (unless `generateComponents` was called by an event handler, which it's not AFAICT) – Dan O May 16 '20 at 23:35
  • I meant binding the function to give it scope to this.state/this.props variables, I don't think the `this` inside the function has the proper scope, no? I've had that happen to me before where `this` is completely different than what I was expecting and would give some strange errors. At the very least I think it's worth trying, might not be the definitive answer though – DrMoney May 17 '20 at 00:00
  • It absolutely does have the proper scope, why would it not? – paolostyle May 17 '20 at 12:20