Transform data after it received from graphql server using vue-composition api - apollo-client

this is my first try of front end developing, so I mostly copy-pasting example is the net.
import {useQuery, useResult} from "#vue/apollo-composable";
export default defineComponent({
name: 'Components',
setup() {
const {result: modulesResult} = useQuery(getModules)
const result = useResult(modulesResult)
return (result)
}
})
I've written the following code and while I can use result in templates (v-for or v-if), I can't find the way how to transform my data.
I want to take the value of result and apply transformation function and pass transformed value to templates. result is vue ref and value is not available if I write ref(result).value right after useResult
const test = ref(result).value
console.log(test) <- undefined

useQuery contains onResult return value, it triggers on data updates, for example
const {onResult} = useQuery(getDerivativeInstruments)
onResult((resultData) => {
instruments.instruments = resultData!!.data.getDerivativeInstruments
instruments.filteredInstruments = resultData!!.data.getDerivativeInstruments
})

Related

How to push Multiple Objects into an array using useState hook

I need to push the Multiple objects in to an array by using UseState hook,
Here I am getting the multiple objects into "getallData", So I need to sent the all the multiple objects into setdataObject. But here I am not getting all the multiple objects data and getting an Empty Array..
const [data, setData] = useState([])
const [dataObject,setdataObject] = useState([{}])
useEffect(()=>{
fetch('http://localhost:3000/results')
.then(res =>res.json())
.then((results)=>{
setData(results);
//console.log(results);
for(let i=0;i<results.length;i++){
//console.log(results);
const getallData={
name :`${results[i].name.first} ${results[i].name.last}`,
money : results[i].price.money.wealth
}
//console.log(getallData);
setdataObject(getallData);
console.log(dataObject);
}
})
},[])
You are calling setdataObject inside a loop. Rather you can add the all datas into an array and set it at the end of the loop. Something like this
const tempArray = []
for(let i=0;i<results.length;i++){
const getallData={
name :`${results[i].name.first} ${results[i].name.last}`,
money : results[i].price.money.wealth
}
tempArray.push(getallData)
}
setdataObject(tempArray);
Another thing. As setState functions are asynchronus so if you call console.log() immediately after changing any state value you will not get the changes immediately. As a result your following code is printing wrong output
setdataObject(getallData);
console.log(dataObject); // WRONG !!!!

console.log(..) of 'reselect' selector displays f()

I'm using react-boilerplate that uses reselect for reading the redux state and maps it to props. I am trying to read the redux state outside a react component (say in custom function defined in myUtil.js).
There is selector in selectors.js:
const makeSelectLoading = () => createSelector(selectGlobal, globalState => globalState.get('loading'));
I import makeSelectLoading into myUtil.js and try to print the value using console.log(makeSelectLoading()). I am expecting the value of the Loading state variable, instead I'm getting the below:
myUtil.js?d403:14 ƒ () {
if (!areArgumentsShallowlyEqual(equalityCheck, lastArgs, arguments)) {
// apply arguments instead of spreading for performance.
lastResult = func.apply(null, arguments);
}
Should I expect this to work? If not, any ideas where I'm going wrong? Thanks!
makeSelectLoading is not a selector itself but a selector factory: a function which returns an actual selector.
In order to use it you should get a selector instance from it and then call the returned instance with the expected arguments.
const getSelectLoading = makeSelectLoading();
const loadingState = getSelectLoading(state);

How to test GraphQL queries with fragments using jest

Problem: I would like to test a GraphQL query that lives in a .graphql file like this:
#import '../../fragments/Widget.graphql'
query WidgetFragment($id: ID) {
readWidgetFragment(id: $id) {
...Widget
}
}
To create a GraphQL schema with mocked resolvers and data, I use makeExecutableSchema and addMockFunctionsToSchema from graphql-tools.
To run the query from inside a jest test, my understanding is that I need to use the graphql() function from graphql-js.
This function needs the query as a string, so I tried two different ways, but neither of them worked:
Parse the .graphql file as a normal text file, giving me the raw string (using the jest-raw-loader in my jest config).
This gives me: Failed: Errors in query: Unknown fragment "Widget". when I run the query.
Parse the .graphql file into a query object using jest-transform-graphql. I believe this should be the right approach, because it should resolve any imported fragments properly. However, to execute the query, I need to pass query.loc.source.body to the graphql, which results in the same error message as option 1.
You can use this:
import { print } from 'graphql/language/printer'
import query from './query.gql'
...
print(query)
Use the initial approach with parsing it as a raw text, except:
use a recursive function with a path argument (assuming you could have nested fragments)
which uses regex to extract all imports beforehand to an array (maybe use a nicer pattern :) )
append the rest of the file to a string variable
then loop through imports, resolving the #imports and passing them to itself and appending the result to the string variable
Finally return the result to the main function where you pass it to the graphql()
Yes, this is quite a pickle. Even with imports correctly working (>= v2.1.0 for jest-transform-graphql, they get added to the query.definitions object, which is completely sidestepped when calling graphql with document.loc.source.body as query argument.
On the server end, graphql (function graphqlImpl) will reconstruct the document object using parse(source) - but it'll have zero knowledge of the imported fragment definitions...
As far as I can tell, the best bet is to stamp fragments to the query source before sending it to the server. You'll need to explicitly find all lines starting with #import and replace these with actual text content of the to-be-imported graphql file.
Below is the function that I use. (Not tested for recursive fragments)
// Async wrapper around dynamic `import` function
import { importQuery } from "./queries";
const importAndReplace = async (fileToImport, sourceDocument, line) => {
const doc = await importQuery(fileToImport);
const targetDocument = (await sourceDocument).replace(line, doc.loc.source.body);
return targetDocument;
};
// Inspired by `graphql-tag/loader`
// Uses promises because of async function `importQuery` used
export default async graphqlOperation => {
const { body } = graphqlOperation.loc.source;
const lines = body.split(/\r\n|\r|\n/);
const bodyWithInlineImports = await lines.reduce(
async (accumulator, line) => {
await accumulator;
const lineSplit = line.slice(1).split(" ");
return line[0] === "#" && lineSplit[0] === "import"
? importAndReplace(lineSplit[1].replace(/"/g, ""), accumulator, line)
: Promise.resolve(accumulator);
},
Promise.resolve(body)
);
return bodyWithInlineImports;
};

Return a Javascript Promise value AKA Keras.js prediction

I'm new to Javascript and getting a bit bogged down with Promises in regards to predictions in Keras.JS
Basically i need to get the prediction value out of a promise (Keras Model) so I can pass it to another function. The following code is taken from the Keras.js github.
var predictions = function () {
model
.ready()
.then(() => {
// input data object keyed by names of the input layers
// or `input` for Sequential models
// values are the flattened Float32Array data
// (input tensor shapes are specified in the model config)
console.log('Model ready',x_pred )
var inputData = {
"input": new Float32Array(x_pred)
};
console.log('input data ready')
// make predictions
return model.predict(inputData)
})
.then(outputData => {
// outputData is an object keyed by names of the output layers
// or `output` for Sequential models
// e.g.,
// outputData['fc1000']
//console.log("outputData", outputData)
const output = new Float32Array(outputData.output)
console.log( output )
})
};
Now, the console reads the contents of my prediction - so the model is doing what I want it to do. But I need to take that prediction and pass it to another function. The following just points to my model promise and the output is undefined.
console.log(outpreds, output)
I understand that this is how the promise is meant to work but once the promise has been fulfilled I would really like to be able to do further things with output. unfortunately as I am using Electron/NodeJS I can't access async/await
Can anyone point me in the right direction?

How would mvc cause non-deterministic ui and redux not

I've read several articals as well as offical docs of redux all of which mention mvc leads to non-deterministic ui while redux not as redux uses pure function. I know that pure function produces same output for same input. But why mutation does not? It would be nice to have an example.
Mutation + asynchronous code can easily lead to functions that don't return the same result given the same input. This is a (very) simplified example with some comments.
// this could be a function in your controller
function delayedAddition(valuePair) {
console.log(
`Getting ready to calculate ${valuePair.x} + ${valuePair.y}`
);
return new Promise((resolve, reject) => {
setTimeout(() => resolve(valuePair.x + valuePair.y), 500);
});
}
const printWithMessage = message => printMe => console.log(message, printMe);
let mutableValuePair = { x: 5, y: 10 };
// this could be a call your view depends on
delayedAddition(mutableValuePair)
.then(printWithMessage('Result is: '));
// MUTATION!
// This could happen in another controller,
// or where ever
mutableValuePair.x = 32;
// Expected result = 5 + 10.
// Result is: 42
// So your view is no longer a function of
// what arguments you pass to your controllers.
If we were using an immutable data structure for valuePair then something like valuePair.setX(32) would not change the original object. Instead we'd get back a new (independent) copy. So you would use it like this instead const modifiedValuePar = valuePair.setX(32). That way, the ongoing calculation (which used the unaffected valuePair) would still give the expected result that 5 + 10 = 15.

Resources