Identify Select Many/Select One attribute of Selection factory - episerver

Is there a way to identify may be through reflection or any other way to identify a property if it is select one or select many.
I have a common selection factory that is both select one & select many as shown in the below image.
I need to perform some operations based on the type of dropdown it is. So is there is any way to determine the select one or many
attribute in the selection factory class
Any inputs is appreciated.

Perhaps I'm missing something, but that sounds like code smell? You should probably refactor the common logic into something separate, and then create two separate selection factories with whatever differs between the two.
With that said, you could probably do something like the following inside your SelectionFactory class:
public IEnumerable GetSelections(ExtendedMetadata metadata)
{
if(metadata.Attributes.OfType<SelectOneAttribute>()?.Any() ?? false) {
// One
} else {
// Many
}
}

Where are you trying to get access to this data? Assuming you have a custom selection factory (here). As you say you can use reflection to get the data within say GetSelections, for an example of the code you need to write, look halfway in this tutorial

Related

Proper way of handling scopes with pivot involved

As a laravel user for a couple of months now, I'm trying to better understand advanced use of Eloquent.
I ran into a case where I can't come up with a solution that feels right.
I've got the following structure (simplified)
Mandate
id
status_id
Mandate_user
mandat_id
user_id
link_status
User
id
I declared belongsToMany in both User and Mandat via the pivot table.
on User:
public function mandates(){
return belongsToMany(..)->withPivot('link_status');
}
I'm able to get accepted mandates for a user by using
public function acceptedMandates(){
return $this->mandates()->wherePivot('link_status', MandateUserStatus::Accepted);
}
This works but I'm wondering if there would be a better way by using scopes or other eloquent methods.
And I'm trying to get accepted mandates that also have a status_id lower than 4 (which comes from an enum as well)
I thought of something like :
public function runningMandates(){
return $this->acceptedMandates()->where('status_id','<', 4);
}
Then gathering mandates like so:
$mandates = User::find(1)->runningMandates();
But would the eloquent way be of doing something like:
$mandates = User::find(1)->mandates()->running()->accepted();
Thanks for your time.
It's a very subjective question and hard to give a straight answer to, but hopefully I can stop you from second-guessing yourself: what you're doing is perfectly fine and no less "eloquent-like" than the other.
Personally I like what you're doing now much more than what you present as the "Eloquent way" and have done so before in professional projects, but ultimately there is a difference in the way you design the code for a framework or package, which must be flexible to account for many different scenarios, most of which you cannot even envision when doing version one, versus how you design the code for an app which will only be consumed by itself. If you know the business logic that drives your app and the views it will present to its users (subsequently, the queries it must perform), why wouldn't you create methods that will easily achieve just that?
Eloquent relies on chaining not just because it's cool, but because it does not know (or care to know) what your business logic is. To me, the "Eloquent way" is more about fluent, readable code, and I find that $user->runningMandates is more readable than $user->mandates()->running()->accepted()->get().
I also find that the first approach is easier to get into. If you're constantly forcing yourself to separate methods so they can be chained, it can be harder to grasp which method is doing what and which method relies on which. Query scopes can modify the query as they like (join, alias, etc) so the danger lies in one method requiring another to come first, because you're conditioning based on a table or column that isn't on the original query, so a method will only work in conjunction with another; or maybe two methods are trying to join the same table, or using the same aliases, so they cannot be used together. It may seem far-fetched, but often the effort to keep things separate and tidy will make your code harder to use. But even if things don't blow up code-wise, the deal-breaker to me would be neglecting business logic: in your case, does it make sense to have two separate scopes for running and accepted? Can a mandate be running if it's not accepted? If not, you should try to prevent a less knowledgeable developer from creating that flawed query (logic-wise). And as you said, the structure is simplified so there may be other gotchas lurking around, and many more will come as the app grows in complexity.
If I'm taking over someone else's code, I'd rather have limited, self-contained methods that don't break over simple, decentralized methods that require you to read (often non-existent) documentation in order to prevent the many ways in which to mis-use them.
Basically, scopes add constraints to the query so you may use the scope approach to modify the query by calling scope methods that will eventually give you a chance to make a query dynamically. So, you may declare (as you did) one relationship method where you may do all the query and call that specific method or use scope methods two build the query using method calls where each method adds a constraint. In this case, it'll be more dynamic but still it's a preference and it gives you more flexibility (IMO). So yes, you can use query scopes for that, for example:
// Declare the main relationship
public function mandates()
{
return $this->belongsToMany(..)->withPivot('link_status');
}
Now, declare query scope for accepted (add a constraint on the query returned by mandates method call)
public function scopeAccepted($query)
{
return $query->wherePivot('link_status', MandateUserStatus::Accepted);
}
Now, add another query scope for running, for example:
public function scopeRunning($query)
{
return $query->where('status_id','<', 4);
}
Now, if you call something likethe following:
$user = User::find(1);
Now, call the relationship method (not as property)
$mendates = $user
->mandates() // The method is called and a query object is constructed
->running() // Add another constraint into the query: ->where('status_id','<', 4)
->accepted() // Add another constraint into the query: ...
->get(); // Finally, execute the query to get the result
Probably, it's clear to you now. Notice the method call mandates(), it's a method call on the relation defined which returns the Query Builder and by chaining additional scope method calls, you are just modifying the query by adding some more constraints but you can do all the query in one method without dynamic scopes, so it's up to you. While, scopes gives you more flexibility but it doesn't mean you've to follow this approach always, it depends.

How can I get the rootNodeID of react element

I need to capture event depend on whether the event target is a special view.
Something like view._rootNodeID === 'event.dispatchMarker'.
But there seems to be no way to get _rootNodeID because the only reference I can get is not the actual ReactNativeBaseComponent but rather something like baking data instance used to construct ReactNativeBaseComponent . And ReactNativeBaseComponent is the one really owns _rootNodeID, if I understand source code correctly.
I can alter react-native source code to achieve what I want but I want to make sure there is no better way.
ReactInstanceMap exists for this.
const ReactInstanceMap = require('ReactInstanceMap');
const inst = ReactInstanceMap.get(view);
view === inst.getPublicInstance();
It seems I always tend to complicate things...Why wouldn't I handle the touch event in that special view directly?
And I must be blind to not notice a property named _reactInternalInstance to refer to the actual element. Although doing so will breaks encapsulation.

Angular lookup value/display value

I have some data on a model that comes in the form of a code such as "US60" and "US70".
I need to take that value and show a display value such as "US 7day/60hour" and "US 8day/70hour". I'm not sure if there is any best practices way to do this in Angular, and I'm not having much luck googling it.
What I would do is have a service that I pass in type and value, and it would return a display value, but as with many things in Angular, since this is my first Angular project, I don't know if it's a good way to do it or not.
I'm just needing to use the display value in html such as {{settings.cycle}} I am already able to access the variable, but I want to show the display value, not the actual value.
If I am getting the gist of your question correctly, you have the value available but want to alter how it is displayed on screen right?
There are two main approaches to do this in Angular, using a directive or a filter.
A filter is basically like a pipe in Unix. You can alter a value before it is being displayed. For example:
{ username | uppercase } will transform the username into an all-caps username. Naturally, you can define your own filters for your use case. Filters are mostly used to transform single values. So for your case, a filter sounds best.
A directive is commonly used to create entire components on a page. For example: <user-profile-card></user-profile-card> would be transformed, using the directive, into the appropriate html/css/logic. So these are used often for larger transformations which involve logic, like server requests. Still these directives could also be used for very small components.
So for your case, although what you are actually want to do is not completely clear to me honestly, a filter seems to be your best shot ;)

GAE filter by missing repeated property

I'm trying to query for all objects that have no value for a given repeated property.
For example imagine you have the following model:
class Foo(ndb.Model):
bar = ndb.IntegerProperty(repeated=True)
and you wanted all the instances of Foo where bar had no value, or is []. How would you perform this query or work around this behavior?
Note (from GAE's ndb documentation):
Querying for a value of None on a repeated property has undefined
behavior; don't do that
Well, like the docs say, you can't.
One way of approaching this might be to keep another property on the model that records how many values it has in bar. You would need to update this when the entity is saved: a good way would be to override put() to do self.bar_count = len(self.bars) before calling the superclass method.
Of course, you'd then need to go through your existing data to set the counts; you might want to use a mapper to do that.

How to avoid a series of "if" statements?

Assume, I have a form ...lets say WinForm... with 'n' number of controls.
I populate them with a default value during the LOAD. Then, the user gets to play with all the controls and set different values for the controls and submit the form. Here is where I find myself writing a series of "if" conditional statements handling the value of each of the controls for (but not restricted to) avoiding nulls, doing validation etc.
Though it works, is there some other more efficient way of doing this instead of disparate "ifs" ?
You may not avoid the 'ifs' entirely, but sometimes it helps to gather related bunch of controls on your Form into User Controls. Then you can move the validation and all from the Form class into individual User Controls, thus reducing clutter.
You should know that WinForms has build in facilities for both validation and data binding. Using these built-in capabilities will definitely result in code that is better structured and easier to write and maintain than hand coding data and validation operations. Beth Massi has done a series of videos that demonstrates these features, you can find them on the MSDN web site.
** Edited **
I don't have a catch-all, as this will vary from form to form, but some general advice.
By the way, I love this question because it's all about keeping your code clean, readable, and doing things as simply as possible.
Use the included validation controls when possible rather than writing if statements to validate code. (see instruction video for winforms (based on the question I'm assuming you mean .Net winforms.) here)
Always look to see if you can write a function to handle repetitive tasks. It takes a line of code to call a function, and if your function is only fivelines long, but you call it tentimes, that means you've saved yourself a lot of duplicate lines of code.
If you can write that function to be smart enough and be able to loop through your controls, so much the better.
In short, look at your code and determine to try to do the job with the least amount of code possible while making it easily readable and understandable, and without resorting to bad practices. Experiment in your spare time on non-production "test" code to refine your technique as you learn, but if you get used to thinking about clean code you get better at writing it.
Create a set of Validators to match 1-for-1 with your controls. Derive from the base Validator a ControlXValidator, which take a ControlX as its constructor, and implements isValid() in the special way that ControlX must evaluate as valid, and implements getDiagnosticMessage to display an appropriate message if the validation fails. Then at the end of your form construction code, create a list of Validators containing the Validator subclass for each control.
Then your validateForm() method can just do something like:
allvalid = True;
foreach(Validator vtor in allValidators)
{
if (!vtor.isValid())
{
StatusBar.Caption = vtor.getDiagnosticMessage();
allvalid = False;
break;
}
}
If you are validating by data-type (dates should look like dates), you could use a function that validates your data and pass the function both the user input and a "sample" of valid data. Valid samples could be stored in an array, keyed by the data-type.
And if the data is not valid, the function returns false and you have one if statement that says "if function returns false, punch the user".
Assume a decently strong language:
Create a hash (a.k.a Map) with the keys as the control identities and the values as functions. Retrieve the function and call.
restrict your control.....life in text box you can set limit of inputr chars ...etc....
not specific to any language: use Guard Clauses is usually a good way to get rid ifs. It is a excellent way to check nulls and validations.

Resources