-
Notifications
You must be signed in to change notification settings - Fork 754
Replace nulls in props from Rails with undefined #1293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace nulls in props from Rails with undefined #1293
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ahangarha we need a test for this functionality
I tried to set up the test environment with appraisal but couldn't get it. At least we have to upgrade appraisal to the latest because the currently-specified version of it doesn't correctly install the dependencies by |
@MaySoMusician May you be more specific? Have you tried to work from this branch? |
With changes in e77835e, the logic is implemented in Ruby side. The implementation may seem tricky and risky, but I think because of the nature of json, I could manage to match only I would like to see if any input can break this logic. I included a highly possible similar match in the tests to ensure it doesn't get replaced. @MaySoMusician May you please check if this solution offers the exact result you are looking for? |
lib/react/rails/component_mount.rb
Outdated
|
||
# This regex matches key:value with null values while ensuing no string with similar | ||
# pattern gets matched. It doesn't include null values in arrays. | ||
props.to_json.gsub(/([^\\]":)null([,}\]])/, '\1undefined\2') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regexps are great for many units tests to demonstrate the regexp is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have made some tests to ensure the regex match "key":null
and only them (not the one similar to them. I think I have tested the most similar situation but I would like to get examples that break the regex.
react_ujs/index.js
Outdated
@@ -108,7 +118,8 @@ var ReactRailsUJS = { | |||
var className = node.getAttribute(ujs.CLASS_NAME_ATTR); | |||
var constructor = ujs.getConstructor(className); | |||
var propsJson = node.getAttribute(ujs.PROPS_ATTR); | |||
var props = propsJson && JSON.parse(propsJson); | |||
var props = propsJson && (ujs.options.replaceNull ? replaceNullWithUndefined(JSON.parse(propsJson)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not a separate var for the parse result to avoid duplicating that bit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the ruby solution is good, all js implementations will be removed.
e77835e
to
2ba7e74
Compare
2ba7e74
to
3f8f482
Compare
The commits for updating lock files are extracted into a PR #1297 to keep the PR focused |
Let's rebase on master. |
data[:react_props] = (props.is_a?(String) ? props : props.to_json) | ||
data[:react_props] = props_to_json( | ||
props, | ||
null_to_undefined: Dummy::Application.config.react.null_to_undefined_props |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@justin808 should we use Dummy::Application
here? Dummy
is just for tests. I suspect it should be Rails.configuration
/ Rails.application.config
(both are the same), no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Agree.
@ahangarha can you get a PR in for this ASAP?
Or @lcmen if you can get us a PR, I'll merge ASAP.
Extra credit if you provide a test that shows this bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the PR was not ready for merge. To me it was still a WIP with good progress.
I am on it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey folks,
Just wanted to chime in that this exact issue is breaking the 3.1.0 gem for me on a fresh Rails app.
Following the installation steps outlined in the README produces:
> rails s
=> Booting Puma
=> Rails 7.0.7 application starting in development
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 5.6.7 (ruby 3.1.2-p20) ("Birdie's Version")
* Min threads: 5
* Max threads: 5
* Environment: development
* PID: 19068
* Listening on http://127.0.0.1:3000
* Listening on http://[::1]:3000
Use Ctrl-C to stop
Started GET "/" for 127.0.0.1 at 2023-08-20 20:15:25 -0400
Processing by HomeController#index as HTML
Rendering layout layouts/application.html.erb
Rendering home/index.html.erb within layouts/application
Rendered home/index.html.erb within layouts/application (Duration: 2.8ms | Allocations: 4135)
Rendered layout layouts/application.html.erb (Duration: 2.9ms | Allocations: 4247)
Completed 500 Internal Server Error in 8ms (ActiveRecord: 0.0ms | Allocations: 8205)
ActionView::Template::Error (uninitialized constant React::Rails::ComponentMount::Dummy
null_to_undefined: Dummy::Application.config.react.null_to_undefined_props
^^^^^):
2: <p>Find me in app/views/home/index.html.erb</p>
3:
4: <!-- erb: paste this in view -->
5: <%= react_component("HelloWorld", { greeting: "Hello from react-rails." }) %>
app/views/home/index.html.erb:5
^C- Gracefully stopping, waiting for requests to finish
=== puma shutdown: 2023-08-20 20:21:16 -0400 ===
- Goodbye!
Exiting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please upgrade to 3.1.1.
Hey! I believe this PR makes our controller specs to crash with a following error:
It comes from |
@lcmen |
Hmm... I don't think Ruby can handle this problem due to the JSON spec. A JSON can't contain My very first post in the discussion has already pointed this out.
Or if you missed my post, you can recognize this limitation by testing the library in a real application (or the test suite, if available...) |
The more I think about this, the more I agree with @justin808 response that this should not be a responsibility of the library. What I would suggest as an alternative, is a some kind of serializer callback function that could be customized via def props_to_json(props, options = { null_to_undefined: false })
return props if props.is_a?(String)
return Rails.configuration.react_props_serializer.call(props) if Rails.configuration.react_props_serializer.present?
# rest of the code
end This way library gives an escape hatch for projects that require more serialization flexibility but does without imposing any additional constraints. |
Update/Rebase to master for #1273 PR.