Knex filter on pre filtered request - sql

I would like to achieve a request in which I can filter my results with where clauses and then apply others where but on the result of the first where
return await UserModel.query()
.withGraphFetched('roles')
.modify(function(queryBuilder) {
if (accessControlFilters.agency_id) {
queryBuilder.orWhere('agency_id', accessControlFilters.agency_id)
}
if (accessControlFilters.third_party.length) {
queryBuilder.orWhereIn('third_party_id', accessControlFilters.third_party)
}
if (accessControlFilters.corporation.length) {
queryBuilder.orWhereIn('corporation_id', accessControlFilters.corporation)
}
})
.modify(function(queryBuilder) {
if (Array.isArray(userFilters.corporation) && userFilters.corporation.length) {
queryBuilder.orWhereIn('corporation_id', userFilters.corporation)
}
if (Array.isArray(userFilters.third_party) && userFilters.third_party.length) {
queryBuilder.orWhereIn('third_party_id', userFilters.third_party)
}
})
.limit(limit)
.offset(offset)
.debug()
But there it just concatenates my first modifier with the second :(
DO you have any clue how i can achieve this ?

Related

Fetch GraphQL data based on variable

I am trying to get my query to react to a ref property.
https://v4.apollo.vuejs.org/guide-composable/query.html#variables
This wont work at all
const { result, variables } = useQuery(gql`
query {
episodes(page: $page) {
info {
pages
count
}
results {
name
}
}
}
`, {
page: 2
});
Tried this as well
setup() {
const currentPage = ref(1);
const { result } = useQuery(gql`
query {
episodes(page: ${currentPage.value}) {
info {
pages
count
}
results {
name
}
}
}
`);
function pageChange() {
currentPage.value += 1;
console.log(currentPage.value)
}
return { result, currentPage, pageChange };
},
This code below works for me when I input page number manually, but I want to pass the page number as variable, because my pagination page increases and I want the query to refresh.
const { result, loading } = useQuery(gql`
query {
episodes(page: 2) {
info {
pages
count
}
results {
name
}
}
}
`,
);
Can someone assist me?
In the link you gave query is followed by the query name.
const { result } = useQuery(gql`
query getUserById ($id: ID!) {
user (id: $id) {
id
email
}
}
`, {
id: 'abc-abc-abc',
})
You don’t specify the query name
Try this instead:
const { result, variables } = useQuery(gql`
query episodes($page: Int) {
episodes(page: $page) {
info {
pages
count
}
results {
name
}
}
}
`, {
page: 2
});
I don’t know what’s your schema looks like but I inferred that page is a Int. If it’s not change Int by the page type

Reactive query definition with Apollo and Vuejs

i try to call a query programaticly eg:
apollo: {
listItems: {
query() {
if (this.listType == "bills") {
return gql`
{
bills {
billId
order {
orderId
customer {
customerId
billingAddress {
title
}
}
}
createdAt
}
}
`;
}
},
property
update: data => data.bills || data.bills
}
}
but when i try this, i get this error:
vue.runtime.esm.js?2b0e:1888 Invariant Violation: Expecting a parsed GraphQL document. Perhaps you need to wrap the query string in a "gql" tag?
I have follow the description in the docs:
https://apollo.vuejs.org/guide/apollo/queries.html#reactive-query-definition
Best regards and thanks four help!
Stay healthy
You cannot wrap apollo query in an if statement. You can use skip instead. In your example it would be like this:
listItems: {
query() {
return gql`
{
bills {
billId
order {
orderId
customer {
customerId
billingAddress {
title
}
}
}
createdAt
}
}`
},
skip() {
return this.listType != "bills"
}
}

Detox get length of element

Hi i'm using detox and i would like to know how can I get the number of matches to
one element(length).
For example "card" match three times, how can I get the three.
const z = await element(by.id("card"))
https://github.com/wix/Detox/blob/master/docs/APIRef.Expect.md
https://github.com/wix/Detox/blob/master/docs/APIRef.Matchers.md
They don't support it in the API /:
z output:
Element {
_invocationManager: InvocationManager {
executionHandler: Client {
isConnected: true,
configuration: [Object],
ws: [AsyncWebSocket],
slowInvocationStatusHandler: null,
slowInvocationTimeout: undefined,
successfulTestRun: true,
pandingAppCrash: undefined
}
},
matcher: Matcher { predicate: { type: 'id', value: 'card' } }
}
A workaround could be
async function getMatchesLength(elID) {
let index = 0;
try {
while (true) {
await expect(element(by.id(elID)).atIndex(index)).toExist();
index++;
}
} catch (error) {
console.log('find ', index, 'matches');
}
return index;
}
then you can use
const length = await getMatchesLength('card');
jestExpect(length).toBe(3);
Here is my solution in typescript:
async function elementCount(matcher: Detox.NativeMatcher) {
const attributes = await element(matcher).getAttributes();
// If the query matches multiple elements, the attributes of all matched elements is returned as an array of objects under the elements key.
https://wix.github.io/Detox/docs/api/actions-on-element/#getattributes
if ("elements" in attributes) {
return attributes.elements.length;
} else {
return 1;
}
}
Then you can use it like this:
const jestExpect = require("expect");
jestExpect(await elementCount(by.id("some-id"))).toBe(2);

Vue computed property: helper function returns undefined despite being defined

I am using a computed property diameter() to return either:
- a random number (randomise: true)
- a number returned from an object within an array (randomise: false).
I do have a working implementation (see bottom of post) but would like to know why the cleaner implementation doesn't work. With randomise: false, diameter() returns undefined. Why?
vars [
{varName: diameter, varValue: 25.8},
{varName: quantity, varValue: 68}
]
computed: {
diameter() {
if (randomise) {
return math.randomInt(100, 1000) //no problems
} else {
console.log(this.populateValue('diameter')) //undefined
return this.populateValue('diameter')
}
}
}
methods: {
populateValue(variableName) {
this.vars.forEach(element => {
if (element.varName === variableName) {
console.log(element.varValue) //25.8
return element.varValue
}
})
}
}
The following implementation works but why do I have to create an arbitrary property to do so?
diameter() {
if (!this.vars || !this.passVars) {
return math.randomInt(100, 1000) / (10 ** math.randomInt(0, 3))
} else {
this.populateValue('diameter')
return this.blah
}
}
populateValue(variableName) {
this.vars.forEach(element => {
if (element.varName === variableName) {
this.blah = element.varValue
}
})
}
The problem is that return element.varValue is returning from the forEach, not populateValue.
There are various ways to write this. e.g.
for (const element of this.vars) {
if (element.varName === variableName) {
return element.varValue
}
}
By using a for/of loop there is no inner function so the return returns from the function you're expecting.
Alternatives include:
let value = null
this.vars.forEach(element =>
if (element.varName === variableName) {
value = element.varValue
}
})
return value
or:
const match = this.vars.find(element =>
return element.varName === variableName
})
if (match) {
return match.varValue
}

Setting validators in Angular on multiple fields

I am trying to find simple way to update the form fields with Validators. For now I do the below:
ngOnInit() {
this.form.get('licenseType').valueChanges.subscribe(value => {
this.licenseChange(value);
})
}
licenseChange(licenseValue: any) {
if (licenseValue === 2) {
this.form.get('price').setValidators([Validators.required]);
this.form.get('price').updateValueAndValidity();
this.form.get('noOfLicenses').setValidators([Validators.required]);
this.form.get('noOfLicenses').updateValueAndValidity();
this.form.get('licenseKey').setValidators([Validators.required]);
this.form.get('licenseKey').updateValueAndValidity();
this.form.get('supportNo').setValidators([Validators.required]);
this.form.get('supportNo').updateValueAndValidity();
this.form.get('purchasedFrom').setValidators([Validators.required]);
this.form.get('purchasedFrom').updateValueAndValidity();
//......others follows here
}
else {
this.form.get('price').clearValidators(); this.form.get('price').updateValueAndValidity();
this.form.get('noOfLicenses').clearValidators(); this.form.get('noOfLicenses').updateValueAndValidity();
this.form.get('licenseKey').clearValidators(); this.form.get('licenseKey').updateValueAndValidity();
this.form.get('supportNo').clearValidators(); this.form.get('supportNo').updateValueAndValidity();
this.form.get('purchasedFrom').clearValidators(); this.form.get('purchasedFrom').updateValueAndValidity();
//......others follows here
}
}
Is this the only way to add and update validators or is there any other way to achieve this. For now I am calling the updateValueAndValidity() after setting/clearing each field.
Update
Something like
licenseChange(licenseValue: any) {
if (licenseValue === 2) {
this.form.get('price').setValidators([Validators.required]);
//......others follows here
}
else{
//......
}
}
this.form.updateValueAndValidity();///only one line at the bottom setting the entire fields.
I done something similar like this
licenseChange(licenseValue: any) {
if (licenseValue === 2) {
this.updateValidation(true,this.form.get('price'));
//......others follows here
}
else {
this.updateValidation(false,this.form.get('price'));
//......others follows here
}
}
//TODO:To update formgroup validation
updateValidation(value, control: AbstractControl) {
if (value) {
control.setValidators([Validators.required]);
}else{
control.clearValidators();
}
control.updateValueAndValidity();
}
If you want to do this for all the controlls inside your form
licenseChange(licenseValue: any) {
for (const field in this.form.controls) { // 'field' is a string
const control = this.form.get(field); // 'control' is a FormControl
(licenseValue === 2) ? this.updateValidation(true,
control):this.updateValidation(fasle, control);
}
}
I did it like below:
this.form.get('licenseType').valueChanges.subscribe(value => {
this.licenseChange(value, this.form.get('price'));
//....Others
}
licenseChange(licenseValue: any, control: AbstractControl) {
licenseValue === 2 ? control.setValidators([Validators.required]) : control.clearValidators();
control.updateValueAndValidity();
}