Compare two customised fields in Yup validation - reactjs

I need to compare two number fields. AreaTo must be bigger than AreaFrom. It works this way:
area_to: Yup.number().min(
Yup.ref("area_from"),
`AreaTo should be bigger than AreaFrom`
),
The problem is I also use custom number formatting in this fields, that returns string, so the field type should be not number but string. But min() is not usable with the strings. I have a function parseNumber(str) that parse number from that string. So I need something like:
area_to: parseNumber(Yup.string()).min(
Yup.ref("area_from"),
`AreaTo should be bigger than AreaFrom`
),
But obviously it don’t work that way. Please help me to implement it properly.

I think you'd want to use test(), and pass in testContext, to reference the other field's value via testContext.parent:
const validationSchema = Yup.object().shape({
area_from: Yup.number().isRequired('Required'),
area_to: Yup.mixed().test('isLarger', 'area_to must be larger than area_from', (value, testContext) => {
if (testContext.parent.area_from > value) return false
return true
})
})
You can read the documentation on this feature here.

At the end this solution worked as expected:
area_to: Yup.string().test(
"area_compare",
`area_to must be bigger then area_from`,
function (area_to: string | undefined): boolean {
return area_to
? parseNumber(area_to) > parseNumber(this.parent.area_from)
: true;
}
),

Related

Sorting in mongoose Express does not sort properly

I need help with sorting in Express working with mongooose db.
When i use sort({'price':1}) everythink is good, but when i pass JSON.stringify(sort) which contains and logs out {"price":1} it stops working. Any ideas why?
if(req.query.sortOption){
const str = req.query.sortOption.split(':');
sort[str[0]] = str[1] === 'desc' ? -1:1;
}
console.log(JSON.stringify(sort));
//here logs out {"price":-1} which works when i pass it into sort function as a string
try {
const annoucements = await Annoucement.find(query)
.skip(page * annoucementsPerPage)
.limit(annoucementsPerPage)
.populate('author')
.sort(JSON.stringify(sort))
res.status(200).json({
status: 'Successfully got an annoucement',
results: annoucements.length,
data: {
annoucements,
},
});
} catch (error) {
res.status(500).json({
status: 'Failed to get all annoucements',
message: error,
});
}
};
How to sort in mongoose?
.sort() takes in an object, and does not take in a string. You used JSON.stringify(sort), which made the sort query into a string, hence mongoose could not parse it.
Solution:
You should just pass .sort(sort) instead of transforming the object to a string.
Explanation:
Mongoose either accepts
a string like "price" (for ascending order) or "-price" (for descending order).
an array (not applicable in this case)
an object, where the key is the property name and the value is the order (1, "asc", "ascending" or -1, '"desc", "descending"`)
What you did was basically pass the string value "{price:-1}" to it, which does not match any of the use cases. Therefore your sorting does not work as expected.

unexpected result in a query in laravel

I’m a beginner in Laravel but have a problem at first. I wrote this query and I’m waiting for Sonya Bins as result but unexpectedly I see ["Sonya Bins"]. what’s the problem?
Route::get('products', function () {
$articles=DB::table('users')->where('id','2')->get()->pluck('name');
return view('products',compact('articles'));
});
pluck will return array if you want to get only single value then use value
// will return array
$articles=DB::table('users')->where('id','2')->get()->pluck('name');
//will return string
$articles=DB::table('users')->where('id','2')->value('name');
// output Sonya Bins
here is an example from the documentation:
if you don't even need an entire row, you may extract a single value from a record using the value method. This method will return the value of the column directly:
$email = DB::table('users')->where('name', 'John')->value('email');
Read more about it here
Hope it helps.
Thanks
pluck() used to return a String before Laravel 5.1, but now it returns an array.
The alternative for that behavior now is value()
Try this:
Route::get('products', function () {
$articles=DB::table('users')->where('id','2')->get()->value('name');
return view('products',compact('articles'));
});
I think it's easier to use the Model + find function + value function.
Route::get('products', function () {
$articles = User::find(2)->value('name');
return view('products',compact('articles'));
});
pluck will return the collection.
I think id is your primary key.
You can just get the first record, and call its attribute's name:
DB::table('users')->where('id','2')->first()->name;
or
DB::table('users')->find(2)->name;
First thing is that you used invalid name for what you pass to view - you don't pass articles but user name.
Second thing is that you use get method to get results instead of first (or find) - you probably expect there is only single user with id = 2.
So to sum up you should use:
$userName = DB::table('users')->find(2)->name;
return view('products',compact('userName'));
Of course above code is for case when you are 100% sure there is user with id = 2 in database. If it might happen there won't be such user, you should use construction like this:
$userName = optional(DB::table('users')->find(2))->name;
($userName will be null if there is no such record)
or
$userName = optional(DB::table('users')->find(2))->name ?? 'No user';
in case you want to use custom string.

How to check an array with regular expression in GraphQL

I need to check the existence of some elements in an array as such
I have an array as such
ar = ['one','two','three']
I want to know how I can individually check the elements in the regular expression code below instead of "/something/" that would map through my array and check if they exist in graphQL one by one.
similar : allCockpitHello (filter: {Association : {value : {regex: "\/something/" }}} limit:2){
nodes{
Name{
value
}
}
You need to have the regex string as an input parameter to be used by the resolver, GraphQL is not going to do the filter for you, you need to do/call that logic in the resolver based on your inputs.
Based on your example, you could have something like this on the schema and resolver:
type Node {
name: String!
}
type NodeQueries {
nodes (filterRegEx :String): [Node]!
}
Once you have the input string on the resolver, the implementation of the filter mechanism is up to you.
const resolvers = {
...
NodeQueries: {
nodes: (parent, params) => {
const {filterRegEx} = params; // regex input string
const ar = ['one','two','three'];
// Create a RegExp based on the input,
// Compare the with the elements in ar and store the result...
// You might end up with ... res = ['one', 'three'];
// Now map the result to match your schema:
return _.map(res, name => ({name}) ); // to end up with [{name: 'one'}, {name: 'three'}]
}
}
...
}
GraphQL is not a magic bullet - it's only a query language, it 'transports' your needs to the engine (local client, remote server ...) where all the necessary processing takes place.
In this case you probably need to pass your array and expression as variables to the server (resolver). If processing is expensive results (similar relation) should be already defined, cached, preprocessed, etc.
If dataset is small you can do this entirely client-side - iterate over an array (fetched using graphql).

how to compare the query value from url to id using react?

i want to check if the url contains ?query_param if so then get its value and compare that value to an id.
consider the url /path/20?query_parm=2234
and i have to get the param_id and compare it with the item id.
so i do something like below,
handle_location = (path) => {
let opened_item, param_id;
param_id = new
URLSearchParams(this.props.location.search).get('query_param');
if (this.state.items) {
opened_item = this.state.items.find(item => item.id ===
param_id);
}
};
the data structure for items is below,
items = [{
id: 2244;
attributes: something;
}
{
id: 33;
attributes: nothing;
}]
But this gives the opened_item value undefined since item.id is never equal to param_id... because of type being different.
How can i fix this...or is there a better way to find the query_param from url and get its value and use it accordingly to find the item that matches with the query_param value.
Given you understand that both data types are different, you could use avoid using strict equality and leverage type coercion which would work
item.id == param_id
The most efficient way though would be to convert param_id to the appropriate type before comparing e.g.
param_id = parseInt(param_id, 10);
It means one conversion and you can keep the strict equality
You will need to either cast both of the values to the same type(either Number or String) and then perform the comparison or you could use == operator which will try to coerce the types automatically(not recommended). You can also always fall back to some default value if none of the items matched the id.
if (this.state.items) {
opened_item = this.state.items.find(item => item.id ===
param_id) || 'some default value'
}
try this:
const param_id = this.props.match.params.id

Angular 2 / Typescript - how to check an array of objects to see if a property has the same value?

This question does it in Javascript, but I would have thought in Typescript I could do some kind of map/filter operation to do the same thing.
I have an array of objects called Room. Each Room has a property called Width (which is actually a string, eg '4m', '5m', '6.5m').
I need to check the entire array to see if all the widths are the same.
Based on that question I have this, but I was wondering if TypeScript has something better:
let areWidthsTheSame = true;
this.qp.rooms.forEach(function(room, index, rooms) {
if (rooms[index] != rooms[index+1]) areWidthsTheSame = false;
});
Any ideas?
FYI the linked question has a comment that links to these performance tests, which are interesting in the context of this question:
This can be done in the following way:
const widthArr = rooms.map(r => r.width);
const isSameWidth = widthArr.length === 0 ? true :
widthArr.every(val => val === widthArr[0]);
We first convert the rooms array to an array of widths and then we check if all values in widths arrays are equal.

Resources