spring-attic / tut-react-and-spring-data-rest

React.js and Spring Data REST :: A tutorial based on the 5-part blog series by Greg Turnquist
https://spring.io/guides/tutorials/react-and-spring-data-rest
882 stars 1.58k forks source link

why "attributes: Object.keys(this.schema.properties)" produces an error "Cannot convert undefined or null to object(…)"? #35

Closed tudoistube closed 7 years ago

tudoistube commented 7 years ago

Hi! First of all, I appreciate for your this tutorial. I am a learner to follow React.js and Spring Data Rest. I have managed to followed your tutorial upto Part 2-Hypermedia Controls. I have also kept my practice source in my github (https://github.com/tudoistube/zspringReact/tree/springReact_step03).

In Part3, I met a error message "Uncaught TypeError: Cannot convert undefined or null to object(…)" in app.js. The Error has been produced in the following procedures : App component call its loadFromServer() in its lifecycle 'componentDidMount'. ↓ follow() function accesses 'employees' resources with its relationship name 'employees' expressed in HAL and pageSize parameter. ↓ then gets 'employeeCollection' data from backend and use client which makes a REST call. ↓ client instance makes a REST call for JSON schema data and embedded promise get employeeCollection. ↓ convert employeeCollection into a form of array to retrieve each individual resources. ↓ The then(employeePromises ⇒ …​) clause takes the array of GET promises and merges them into a single promise with when.all(), resolved when all the GET promises are resolved. ↓ Finally, loadFromServer wraps up with done(employees ⇒ …​) where the UI state is updated using this amalgamation of data. My problem has occurred at "attributes: Object.keys(this.schema.properties),".

q_springreact_json error

With an attached capture image, it shows a console output message "Uncaught TypeError: Cannot convert undefined or null to object(…)", I have searched and I just only guessed it might be necessary to declare this.schema with a datatype before 'this' makes a property of schema and receive 'schema.entity'. I am still familiar with declaring this' property only in component's constructor.

As I afraid of too much comment in my source kept in my gitHub(https://github.com/tudoistube/zspringReact/blob/springReact_step03/zspringReact3_Part03/src/main/js/app.js ), I used the same file 'app.js' from here and have run it again but failed with the same console message as above.

Is there any changes except App.js file in Part3? I think only App.js has been modified in Part3.

Thanks for reading my questions and hope to find any clue to solve this problem.

starobrat commented 7 years ago

Hi, Can you share your api outputs generated using curl?

My guess is that you don't have Lombok installed correctly. Because of that there are no getters and setters generated automatically on the server side and API doesn't return actual employees properties.

Regards, Piotr

tudoistube commented 7 years ago

Hi, firstly thank you for your comments.

At first, I thought it happened because I created a springboot by copying part2's springboot. Because I could see the fact that the name of springboot was not its name, when I run the springboot on STS. You can see the captured image here : https://github.com/tudoistube/zspringReact/issues/1#issuecomment-261124463 Because I wanted to keep all the comments from part 1, so I copied and created a new springboot. I fixed the name of main java class to part3, and it worked. Then I thought I cleared this problem and uploaded two good sources to my github and closed it. https://github.com/tudoistube/zspringReact/tree/springReact_step03

But the problem was not solved in fact. Because I still have another two tasks (Part4 and Part5), I reproduced the same source and ran it but got the same error as above captured image. I am using node v6.9.1 and npm 3.10.8 on a 64bit win7 notebook.

I hope to know why an error of 'Uncaught TypeError: Cannot convert undefined or null to object(…)' happens at "attributes: Object.keys(this.schema.properties),".

I believe a combination of Springboot and React will be a clever choice, so I want to get any hint to solve this problem.

Thanks and Regards. Tudoistube

gregturn commented 7 years ago

Essentially, the webpack configuration in this tutorial is designed to compile all the code using babel.js with an ES2015 profile. This means that you can use such new APIs, and they will be compiled into ES5-compliant code that SHOULD work on any browser.

That requires that you actually run the webpack build steps, an npm task you'll find in package.json, executed by the frontend-maven-plugin.

tudoistube commented 7 years ago

Good Morning! Thanks a lot for your reply. Everytime I run a springboot as following procedures :

  1. nvm run watch ("watch": "webpack --watch -d")
  2. run a springboot app either by STS or ./mvnw spring-boot:run As I produce a bundle.js before running a springboot app, is it the same with what you meant? Please let me know if there is any action that I missed. I also appeal to a clue in React.js group with your comments as following url : https://www.facebook.com/groups/react.ko/permalink/1759792380947593/

Thanks and Regards. Tudoistube

tudoistube commented 7 years ago

After break, I created a new springboot and copied sources from previous one. Now, it even teases me... I mean it oddly runs, and mostly did not run.

Is it possible to mess values in memory among themselves? I did STS > Project > Clean on STS and 'npm cache clean' but failed to clear this problem. Is there any way to clean the old aggreated value in memory?

q_springreact_memory clear

As I called http://localhost:8080/ so many times all day long, as attached captured image, when I run the springboot they are all different among the output of Chrome, Firefox and the source of DatabaseLoader.java and app.js.

There is no 'Frodo2' and '2Do' in DatabaseLoader.java file, but Chrome shows them and Firefox strangely shows two empty rows.

And I intentionally wrote 3dots like 'First Name...' in the table of EmployeeList component in app.js file. Then I used 'npm run watch' to get a build file, and I ran a springboot. But there is no change.

I do not believe magic, but it works as if it has a magic :-);;;

gregturn commented 7 years ago

Smells like browser caching. Either use am incognito tab or open up dev tools and ensure caching disabled when using the tools.

tudoistube commented 7 years ago

Yes, I think it has something with old memory values in somewhere. Now, I deleted all other springboot from STS, and I have only left one working springboot. Even it repeats working and fail. When it work on browser, it shows values from other already closed project's DatabaseLoader.java. It's the first experience to recognize browser caching. Is there any other function enough to cleanse browser caching? I also searched and found a function called 'the garbage collector' in Chrome as following url : http://stackoverflow.com/a/40194782 Or it there any other way to garbage collect in my programming source?

Thanks and Regards. Tudoistube

gregturn commented 7 years ago

Chrome's developer tools have the option to disable caching when the tools open. I wish it was the default.

Also, ensure you restart the Boot app after making JS changes, and after webpack has rebuilt bundle.js.

tudoistube commented 7 years ago

I've got a good news. I think it seems working successfully now according to your mention. In my Chrome's developer tools, my default was unchecked on Disable cache so far. I checked and ran it again. Now it shows only values from its DatabaseLoader.java file.

But is there any other way to prevent this from happening in my programming area? Because I can not force users to check this function in Chrome, so I would like to implement it not necessary for users to do something.

Is it right to 'npm run watch' which calls scripts "webpack --watch -d" in package.json because you emphasize that 'ensure you restart the Boot app after making JS changes, and after webpack has rebuilt bundle.js'?

I will test some more and close this thread if there is no more problem.

Appreciate a lot for your help and Regards. Tudoistube

gregturn commented 7 years ago

Yes I run the watch task while writing JS code.

tudoistube commented 7 years ago

Good Morning, Greg! Thanks for all of your help. Through adding my comments to your source line by line numerous times, I have found out the cause of this Error message. It was caused that I did not notice the change in render() of the EmployeeList Component from Part2 to Part3 as followings : Part2 : var employees = this.props.employees.map(employee => '<Employee key={employee._links.self.href} employee={employee} onDelete={this.props.onDelete}/>); Part3 : var employees = this.props.employees.map(employee => '<Employee key={employee.entity._links.self.href} /...★I missed the 'entity'. employee={employee} attributes={this.props.attributes} onUpdate={this.props.onUpdate} onDelete={this.props.onDelete}/>);

Except your document and like Java API online document. Because there are React.js, npm, Node.js and Javascript in this app.js file, and I do not know the usage of '{employee.entity._links.self.href}' belong to which area among them. In this case, is there any document which I can understand the difference between '{employee._links.self.href}' and '{employee.entity._links.self.href}' for myself? Would you introduce me a good reference site or document which enables me to think how to catch a fish for myself, rather than receiving a fish from other's help?

Appreciate a lot for your help and Regards. Tudoistube