-
Notifications
You must be signed in to change notification settings - Fork 59
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
Sugar api for state/props configuration boilerplate #136
Comments
One thing to note is that when dealing with STATE vs PROPS. We almost never pass a validator into STATE because it is internal and a specific type should already be expected. Currently in our project we have been doing something like this where const CONFIG = {
onChange: Types.func, // Default is to accept validator function
editing: Types.bool,
stickyTime: Types.number
};
const STATE = {
items_: [] // Default is to accept initial value
};
Component.STATE = createState({CONFIG, STATE}); Now the one thing we could add on top of this is what you mentioned So if this was included within metal's api plus a metal-state-validators change a basic example might look like Component.PROPS = {
active: Types.bool.value(false),
id: Types.number.required(),
onChange: Types.func
};
Component.STATE = {
items: [],
open: false
}; I like the example above, but it may be strange that we handle STATE and PROPS differently with the initial values. |
Yeah, I think it's best to keep both using the same api. When using soy we don't separate between state and props btw, there's only STATE and you can use a property to indicate if it's going to be internal or not. Also, validators can still be useful even for internal state, developers can still pass a wrong value by mistake, or get it from somewhere else, and this can help debug it. It'll be more consistent to have it work the same way everywhere, and also more powerful. Besides, the Also, I think that |
One thing we will have to worry about is Ill have to think about this more and look at our use cases |
Could you explain why they'd get messy? |
Say we have something like STATE = {
foo: Config.shapeOf(
{
bar: Config.string,
baz: Config.number
}
).value(
{
bar: 'test',
baz: 3
}
).required
} Just seems messy in my opinion. Granted, this is also just how Liferay would require formatting standards. But then again, if we have a shape and default value of an object, there may be no way of getting around that. So you may be right actually. It might not be as bad as I think. |
One more thing, which may belong more over at To the component being "connected", all values received from the store and Were wondering if this is something that should be achieved through an API, or maybe just source formatting. |
@bryceosterhaus since this is supposed to be sugar it means that you don't have to use this syntax every time. In the use case you showed it'd maybe be better to just use the original format instead, since it's big anyway. @mthadley: yes, I think this would live in metal-redux like you said, since Metal.js doesn't know about it at all. We could add the option of setting the props used in |
Created a related issue at metal/metal-redux#8. |
So after looking into it a bit more, I like your proposal. Would it be possible to import the Here is a sample of how we would be using it in our components with also having a store import Component, {Config} from 'metal-jsx';
class MyComponent extends Component {
//...
}
MyComponent.STATE = {
count: Config.value(5),
loading: Config.value(true)
};
const STORE = {
creator: Config.instanceOf(Map).required
};
MyComponent.PROPS = {
...STORE,
id: Config.number.required
items: Config.array.value([])
onChange: Config.func.required
};
|
Another thing is that in the way I'm thinking of this you'd actually need to call each config function, not just reference it, since each call will need to make some changes to the returning object for Metal.js to use it later. So the api should be more like |
That would be great. Both cases work for me. |
@mairatma this sounds great! Do you have an idea of when you'll be able to work on this, or if you would like us to help in any way? As a team we've realized that before we are able to release Loop using Metal we are going to need to convert to Metal 2.x due to the way it handles refs. We also don't want to spend the time converting everything to the new way of handling State and Props until we have this sugar syntax ready as well. Thanks. |
Sure, since we're agreed I'll see if I can do this today, and have it ready tomorrow at the latest so that you can start converting :D |
This |
Done, this is already available in version 2.1.0 :) |
Oh, and just to make it clearer, we've moved metal-state-validators to this repo, since it's also required for the sugar api to work, and it's really quite useful. I've added an explanation to the original repo's README file about this. |
One feature that we've promised to work on is to create some kind of sugar api for configuring state/props, so that common use cases can avoid boilerplate.
The plan is to add that to version 2.0.0, which has already been released, but I wanted to first get more details about how everyone would prefer this to work.
From what we talked about the most common use cases are of using just the validator. That requires you to type something like this:
So we could allow a simpler usage, where if you set the config to a function we'll assume that you're passing just a validator.
If I remember correctly we also talked about passing the value directly as the config, if only value was to be set, like this:
That would conflict with the validator sugar though, since value can also be a function, so in that case we won't know which of the two it's supposed to be. So, if validator is the most useful one we could add just that.
I was thinking about this though, and thought that instead of adding this sugar directly on Metal.js, we could instead create a new project (or maybe change metal-state-validators for this) to build and return the right config object that Metal.js expects. That way we can have an api that could work as sugar for more use cases.
For example, instead of something like this:
We could have the option of doing something like:
Each of these calls could return an object with a config key that has the format Metal.js expects, as well as more functions you can call to add data to it. In Metal.js we'd just need to accept an object with a config key that has the expected format to have this work.
What do you think?
The text was updated successfully, but these errors were encountered: