Is there any advantage to use Select decorator instead of select method? - ngxs

#Select(state => state.animals)
animalsWithDecorator$: Observable<string[]>;
and
animalsWithMethod$ = this.store.select(state => state.animals);
It looks like the select is more type safe because if state.animals changes its type to number[] animalsWithMethod$ also changes it but animalsWithDecorator$ would still be string[].

Some of the advantages are mentioned in the docs.
So, the second approach would be more useful for:
having programmatic selectors
selecting the state (or part of it) just once without continuously watching it
unit testing

Related

Overriding cy.get with a custom command to default to using data-cy?

I'm trying to use data-cy as much as I can in my code.
It's slightly tedious having to write cy.get('[data-cy=name]') all the time.
Is it possible to create a custom command that would by default try and find a data-cy first.
So if I wrote cy.get('name') it would try and find data-cy="name" on the page, if I used cy.get('.class') it would try and find a class with class on the page, if I used cy.get('#id') it would try and find an id with 'id` on the page?
Basically, I just want cy.get() to default to trying to find data-cy first and then work as it originally does if I pass in anything else to it.
It's a nifty idea, but you are leaning towards conditional testing if you try to do all-in-one.
I would have a custom command for data-cy and stick with cy.get() for the other selectors
Cypress.Commands.add('attr', { prevSubject: false }, (attr) => {
return cy.get(`[data-cy="${attr}"]`)
})
cy.attr('name')
Selecting UI elements based on an attribute, such as data-cy, is even described in the Cypress best practices section here.
There is also an example on how to create a custom command to have a common way for selecting the elements here.
The examples look like:
// cypress/support/commands.ts
Cypress.Commands.add('getBySel', (selector, ...args) => {
return cy.get(`[data-cy=${selector}]`, ...args)
})
Cypress.Commands.add('getBySelLike', (selector, ...args) => {
return cy.get(`[data-cy*=${selector}]`, ...args)
})
The first command looks for an exact data-cy attribute match. The second one looks for elements containing a data-cy like the provided argument.
If you add Cypress Testing Library to your project you get a bunch of commands around the data-testid attribute
ByTestId - find by data-testid attribute
getByTestId
queryByTestId
getAllByTestId
queryAllByTestId
findByTestId
findAllByTestId
See Cheatsheet for differences.
If you are tired of typing cy.get('[data-cy=name]'), then this profusion of selection methods may vex you even more.
The interesting part is the discussion about what selection methods are best for testing.
See Priority
Based on the Guiding Principles, your test should resemble how users interact with your code (component, page, etc.) as much as possible.
Interestingly, they place *ByTestId at the bottom of the list
The user cannot see (or hear) these, so this is only recommended for cases where you can't match by role or text or it doesn't make sense (e.g. the text is dynamic).

Append new request example to drf-spectacular schema

I know the way to add examples for the schema used by drf-spectacular is:
examples=[
OpenApiExample(
'Example 1',
description='longer description',
value='example'
),
]
However, instead of creating from scratch the examples, I would like to add a new one to the one that is automatically generated.
Is there a way to do this? Or at least, generate the request body fro the serializer.
Thanks!
drf-spectacular does not generate examples by itself. Uunless you provide OpenApiExample instances. the schema will not contain examples. If you see an example it is because your UI (swagger/redoc) came up with one based on the given types. I assume they stop doing this once you provide an actual example.
I think that makes sense once you indicate that you take care of your examples yourself. In any case it would be a setting in the UI as this has nothing to do with spectacular.

How can I use an observable to perform a recursive search without going over duplicates?

I'm going to phrase the question in rxjs, but I suppose it's similar for any Rx or observable library.
Say I have an observable of users, and a function getAssociates(user) that returns another observable of users. I want to use the getAssociates function on every user in the observable and return an observable of those associates. flatMap is enough for this.
But I also want to run getAssociates on each associate that comes back, but without ever running it twice on any given user (since two users might share an associate, and if A has B as an associate, then B also has A as an associate).
Something like the expand operator is what I think I'm looking for:
seedUsers.pipe(
expand(user => getAssociates(user)),
);
but how can I get in the bit about not running twice on any given user? I could maintain a list of seen users, but I'd like to achieve it in a functional style.
Conceptually, you need to :
Keep track of the known users, for example using a Set
Filter the known users before making a request, for example using filter operator
Here is a suggestion :
let knownIds = new Set();
getAllItems(Ids){
return from(Ids).pipe(
filter(id => ! knownIds.has(id)),
concatMap(id => getAllItems(id)),
map( id => knownIds.add(id))
)
}
getAllItems([originalId]).subscribe( allItems=> console.log)
Notes:
I guess you could manage to do it using rxjs, but none of the solutions I can think of is simpler than using a set + filter.
I used concatMap to ensure you don't run the request twice. Using mergeMap (flatMap), you could have a scenario like this :
---------Req(user1)----------------------------resp(user1)-------------------------
---Req(user2)--------resp(user2)--Req(user1)-----------------resp(user1)-
But if you accept having eventually more than 2 requests per user, you can use flatMap to gain speed.

How to perform a NOT query with postgres_ext

Is it possible to perform a NOT type query with chained methods using postgres_ext?
rules = Rule.where.overlap(:tags => ["foo"])
Basically want the inverse of the above. Thanks!
In regular active record you can use .where.not as described in this article: https://robots.thoughtbot.com/activerecords-wherenot however looking through the source code of postgres_ext I don't know if it is defined in that library. You may be able to construct your query in a way that uses the native active record methods.

What is the 'right' data structure to turn app features on/off based on 'type' of account?

My app has 10 features that are enabled/disabled depending upon which of the 3 'types' of account a user has.
Currently, I have 10 methods (one per feature) along the lines of:
def is_FEATURENAME_enabled
case currentuser.accounttype
when "A", "C" # account types allow to see that feature
return true
else
return false
end
end
Then, in each place where I potentially disable a feature, I do
if foo.is_SOMEFEATURE_enable
do stuff to enable that feature
end
It works. It's not that hard to maintain. But there should be a better way. I suspect the right solution is to define some sort of structure (hash? I dunno) in one place that maps enabled features to accounttypes, then have a single method that I call something like:
if foo.is_feature_enabled(:FEATURENAME)
do stuff to enable feature
end
where the method is_feature_enabled looks at currentuser.accountype and checks the mapping structure to see if the identified feature is enabled.
And I suspect the DRY way to define that mapping (given I have WAY more features than account types) is to list all the features ONCE then for each feature list the accounttypes that have access to that feature (not the other way around). That way when I add a new feature I only have to edit ONE line in the mapping. Something like:
FeatureA: usertype1
FeatureB: usertype1, usertype3
FeatureC: usertype2
...
seems more logical and easier to maintain than:
usertype1: FeatureA, FeatureB, FeatureD, FeatureG
usertype2: FeatureC, FeatureD
usertype3: FeatureB, FeatureD, FeatureG, FeatureH
Any suggestions would be appreciated, and instructive for learning The Right Way to do stuff in ruby.
I think you've pretty much discovered the best way to do it on your own-- what you suggest is wise. Just use the feature name as a lookup key for your hash, then take the resulting list and check whether that list contains the account type of the current user.
E.g.,
# For example...
$AllowedUserCastes = {
:CanLogin => ["admin", "paiduser", "crazyuser", "anonymous"],
:CanDrink => ["admin", "21yearolduser", "crazyuser"],
:CanArrest => ["admin", "police"]
}
def featureAllowed?( whichFeature )
$AllowedUserCastes[whichFeature].include? currentUserCaste()
end
It sounds like you're looking for some kind of event dispatcher. I've yet to bump into a very good one in ruby. But I'm sure I've missed a few, so I'll be happy to be stood corrected in the comments.

Resources