react-query: QueryOptions not working when using userQueries() - javascript

When passing some "query options" while using useQueries() to fetch multiples queries at the same time, these "query options" are not been applied on any query execution (eg: refetchOnWindowFocus is true and I want it to be false).
Example
const slidesID = ['11111', '22222', '33333'];
const COMMON_QUERY_OPTIONS = {
retry: false,
refetchOnWindowFocus: false,
refetchOnMount: false,
} as const;
const slideQueries = useQueries(
slidesID.map((slideID) => {
return {
queryKey: ['slides', 'slide', slideID],
queryFn: () => getSlide(slideID),
COMMON_QUERY_OPTIONS,
};
}),
);

The problem is you are passing in the WRONG way the "query options".
There are two similar but different ways of executing useQuery:
a) common way ( just the 3er param is an {object} )
const result = useQuery(queryKey,queryFn, {
retry: false,
refetchOnWindowFocus: false,
refetchOnMount: false,
} )
b) the object syntax way (all the params are at the same level inside a global object)
const result = useQuery({queryKey, queryFn, retry: false,
refetchOnWindowFocus: false,
refetchOnMount: false,
})
In your example, you are using the 'the object syntax way' but passing the "query options" as the 'common way'. To fix it just apply a ...spread to correctly pass the options.
FIXED Example
const slidesID = ['11111', '22222', '33333'];
const COMMON_QUERY_OPTIONS = {
retry: false,
refetchOnWindowFocus: false,
refetchOnMount: false,
} as const;
const slideQueries = useQueries(
slidesID.map((slideID) => {
return {
queryKey: ['slides', 'slide', slideID],
queryFn: () => getSlide(slideID),
...COMMON_QUERY_OPTIONS, //notice the ... here
};
}),
);

Related

How to change param from outside

I need to change lang value on export const GetWeatherDetails = ( location ="Paris", lang= 'en'), what would be the proper way to do it, it's an Action.js file so I need to get it done from App.js or another file in this case I got Weather.js
export const GetWeatherDetails = ( location ="Paris", lang= 'en') => async dispatch => {
dispatch({ type: GET_WEATHER.PENDING });
axios
.get(BASE_URL, {
params: {
q: location,
lang: lang,
units: "Metric",
}
})
.then(response =>
dispatch({ type: GET_WEATHER.SUCCESS, payload: response.data })
)
.catch(err => {
console.log(err.response, err);
toast.error(err.response.data.message, {
position: "bottom-center",
autoClose: 2000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: false,
draggable: false
});
dispatch({ type: GET_WEATHER.REJECTED, payload: err.response });
});
};
As #IronGeek pointed out, lang is the second argument to the GetWeatherDeatils function. It's predefined with the "en", so that if you call GetWeatherDetails without the second argument, "en" is used. For example:
GetWeatherDetails('Berlin')
If you want to pass in another value, just call GetWeatherDetails with other values:
GetWeatherDetails('Berlin', 'de')
You can read more about default function arguments at MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters

Quasar QSelect is not opening when performing AJAX call

I have been trying to create a simple auto complete using Quasar's select but I'm not sure if this is a bug or if I'm doing something wrong.
Problem
Whenever I click the QSelect component, it doesn't show the dropdown where I can pick the options from.
video of the problem
As soon as I click on the QSelect component, I make a request to fetch a list of 50 tags, then I populate the tags to my QSelect but the dropdown doesn't show.
Code
import type { PropType } from "vue";
import { defineComponent, h, ref } from "vue";
import type { TagCodec } from "#/services/api/resources/tags/codec";
import { list } from "#/services/api/resources/tags/actions";
import { QSelect } from "quasar";
export const TagAutoComplete = defineComponent({
name: "TagAutoComplete",
props: {
modelValue: { type: Array as PropType<TagCodec[]> },
},
emits: ["update:modelValue"],
setup(props, context) {
const loading = ref(false);
const tags = ref<TagCodec[]>([]);
// eslint-disable-next-line #typescript-eslint/ban-types
const onFilterTest = (val: string, doneFn: (update: Function) => void) => {
const parameters = val === "" ? {} : { title: val };
doneFn(async () => {
loading.value = true;
const response = await list(parameters);
if (val) {
const needle = val.toLowerCase();
tags.value = response.data.data.filter(
(tag) => tag.title.toLowerCase().indexOf(needle) > -1
);
} else {
tags.value = response.data.data;
}
loading.value = false;
});
};
const onInput = (values: TagCodec[]) => {
context.emit("update:modelValue", values);
};
return function render() {
return h(QSelect, {
modelValue: props.modelValue,
multiple: true,
options: tags.value,
dense: true,
optionLabel: "title",
optionValue: "id",
outlined: true,
useInput: true,
useChips: true,
placeholder: "Start typing to search",
onFilter: onFilterTest,
"onUpdate:modelValue": onInput,
loading: loading.value,
});
};
},
});
What I have tried
I have tried to use the several props that is available for the component but nothing seemed to work.
My understanding is that whenever we want to create an AJAX request using QSelect we should use the onFilter event emitted by QSelect and handle the case from there.
Questions
Is this the way to create a Quasar AJAX Autocomplete? (I have tried to search online but all the answers are in Quasar's forums that are currently returning BAD GATEWAY)
What am I doing wrong that it is not displaying the dropdown as soon as I click on the QSelect?
It seems updateFn may not allow being async. Shift the async action a level up to solve the issue.
const onFilterTest = async (val, update /* abort */) => {
const parameters = val === '' ? {} : { title: val };
loading.value = true;
const response = await list(parameters);
let list = response.data.data;
if (val) {
const needle = val.toLowerCase();
list = response.data.data.filter((x) => x.title.toLowerCase()
.includes(needle));
}
update(() => {
tags.value = list;
loading.value = false;
});
};
I tested it by the following code and mocked values.
// import type { PropType } from 'vue';
import { defineComponent, h, ref } from 'vue';
// import type { TagCodec } from "#/services/api/resources/tags/codec";
// import { list } from "#/services/api/resources/tags/actions";
import { QSelect } from 'quasar';
export const TagAutoComplete = defineComponent({
name: 'TagAutoComplete',
props: {
modelValue: { type: [] },
},
emits: ['update:modelValue'],
setup(props, context) {
const loading = ref(false);
const tags = ref([]);
const onFilterTest = async (val, update /* abort */) => {
// const parameters = val === '' ? {} : { title: val };
loading.value = true;
const response = await new Promise((resolve) => {
setTimeout(() => {
resolve({
data: {
data: [
{
id: 1,
title: 'Vue',
},
{
id: 2,
title: 'Vuex',
},
{
id: 3,
title: 'Nuxt',
},
{
id: 4,
title: 'SSR',
},
],
},
});
}, 3000);
});
let list = response.data.data;
if (val) {
const needle = val.toLowerCase();
list = response.data.data.filter((x) => x.title.toLowerCase()
.includes(needle));
}
update(() => {
tags.value = list;
loading.value = false;
});
};
const onInput = (values) => {
context.emit('update:modelValue', values);
};
return function render() {
return h(QSelect, {
modelValue: props.modelValue,
multiple: true,
options: tags.value,
dense: true,
optionLabel: 'title',
optionValue: 'id',
outlined: true,
useInput: true,
useChips: true,
placeholder: 'Start typing to search',
onFilter: onFilterTest,
'onUpdate:modelValue': onInput,
loading: loading.value,
});
};
},
});

Javascript - Set default values for object optional fields in function params [duplicate]

This question already has an answer here:
ES6 Object Destructuring Default Parameters
(1 answer)
Closed 1 year ago.
function myFunction(data, options = { merge: true, cache: false }) {
console.log({ merge: options.merge });
console.log({ cache: options.cache });
console.log("----------------------");
}
myFunction({}, { cache: true });
myFunction({}, { merge: false });
myFunction({});
How can I do, in the above example, to avoid losing the default value of the optional field "merge"?
Another way is to use the fallback values feature of destructuring
function myFunction(data, options = {}) {
const {merge = true, cache = true} = options;
console.log({merge});
console.log({cache});
console.log("----------------------");
}
You can use default value assignment with the destructuring assignment notation
{ merge = true, cache = false } = {}
function myFunction(data, { merge = true, cache = false } = {}) {
console.log({ merge: merge });
console.log({ cache: cache });
console.log("----------------------");
}
myFunction({}, { cache: true });
myFunction({}, { merge: false });
myFunction({});
One of the ways:
function myFunction(data, options) {
options = {merge: true, cache: true, ...options}
console.log({merge: options.merge});
console.log({cache: options.cache});
console.log("----------------------");
}

Got different answer from a return of a function

I'm blocked since few hours now, I wish somebody can help me figure out what I do wrong.
This whole code is to get a json response from an API. I want to understand what are my errors, so please, explain a little ! ;)
const fetch = require('node-fetch');
const Bluebird = require('bluebird');
fetch.Promise = Bluebird;
const xml2js = require('xml2js');
module.exports = {
getImage : async function (tag, random){
let url = "anApiLink" + tag;
if(random != null) url = "anApiLink" + tag + "&id=" + random;
const get_data = async url => {
try {
const response = await fetch(url);
if(! response.ok) return new Error("Erreur lors de la récupération de l'image : " + response.statusText);
const text = await response.text();
const xmlToJson = await xml2js.parseString(text, (err, result) => {
if(err) throw err;
const json = JSON.stringify(result, null, 4);
return json;
});
console.log(xmlToJson);
return xmlToJson;
} catch (err) {
console.error(err);
}
};
return get_data(url);
}
}
My json const is what I want to return from the global function (get_data), and it's an actual good json answer. With my final return, I actually get what's below.
From my console.log() :
{
comment: '',
sgmlDecl: '',
textNode: '',
tagName: '',
doctype: '',
procInstName: '',
procInstBody: '',
entity: '',
attribName: '',
attribValue: '',
cdata: '',
script: '',
c: '',
q: '',
bufferCheckPosition: 65536,
opt: { trim: false, normalize: false, xmlns: false, lowercase: undefined },
looseCase: 'toUpperCase',
tags: [],
sawRoot: false,
closedRoot: false,
closed: false,
error: null,
tag: null,
strict: true,
noscript: true,
state: 0,
strictEntities: undefined,
ENTITIES: {},
attribList: [],
trackPosition: true,
column: 0,
line: 0,
position: 0,
errThrown: false,
onerror: [Function],
onend: [Function],
ended: true,
onopentag: [Function],
onclosetag: [Function],
ontext: [Function],
oncdata: [Function],
startTagPosition: 781
}
Thanks for the help.
Salut, I didn't even realize at first that I was reading french in your code... Your problem seemed to be related to that library you're using, xml2js. I took a look at their docs, and maybe this may help you.
The function itself does not return the result, but you can get it in the callback, that's the reason why you're logging this weird object. You could create a separate var to store the result, but I have a better solution.
If you want to use promises, I found this in the docs, and this in the source code about parseStringPromise, and I think that's what you want. The source code indicates that the result is returned as a Promise here.
In short, what you return in the callback isn't returned by parseString. This is what xmlToJson should be to act as intended.
// Not tested. I might have made an error about the location of 'then', not sure.
const xmlToJson = await xml2js.parseStringPromise(text)
.catch(e => throw e)
.then(r => JSON.stringify(r, null, 4))

Transfer function for "eosio.token" smart contract is not working

const network = {
blockchain:'eos',
protocol:'https',
host:'jungle2.cryptolions.io',
port:443,
chainId: 'e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473',
sign: true,
broadcast: true,
debug: true,
verbose: false,
}
try {
const scatterInfo = await ScatterJS.scatter.connect('eosbetdice');
console.log({scatterInfo})
if ( scatterInfo ) {
const scatter = ScatterJS.scatter;
const requiredFields = { accounts:[network] };
const scatterVal = await scatter.getIdentity(requiredFields);
console.log({scatter,scatterVal})
if ( scatterVal ) {
const account = scatter.identity.accounts.find(x => x.blockchain === 'eos');
console.log("account",account)
const result = await api.transact({
actions: [{
account: 'eosio.token',
name: 'transfer',
authorization: [{
actor: account.name,
permission:'active',
signatures:[signature],
available_keys:[account.publicKey]
}],
data: {
from: 'abceristest2',
to: account.name,
quantity: betAsset,
memo: memo
},
}]
}, {
blocksBehind: 3,
expireSeconds: 30,
});
console.log({result})
return result;
}
} return false;
} catch ( exception ) {
console.log( exception )
}
I expect the transfer function will be work fine but It give me 401 unauthorized error. This transfer function hit the api of jungle testnet , "http://jungle.eosgen.io/v1/chain/get_required_keys"
How I can authenticate this function?
Error which I got, when this transfer function run
I don't check your codes in detail, but I think it is needed to set the data of "abceristest2" to authorization parameter.

Categories