Error when trying to unmask relay modern fragment that has arguments - relayjs

I've got the following query:
query ChatRefetchContainerRefetchQuery(
$arg: ID!
$arg2: Boolean!
) {
...PeopleFragment
#arguments(arg: $arg, arg2: $arg2)
}
What I want todo is unmask the ContainerFragment data OUTSIDE of the fragment. Usually you can use #relay(mask: false), however the relay compiler errors with the following message:
ERROR:
RelayMaskTransform: Cannot unmask fragment spread `PeopleFragment` with arguments. Use the `ApplyFragmentArgumentTransform` before flattening
Query that errors:
query ChatRefetchContainerRefetchQuery(
$arg: ID!
$arg2: Boolean!
) {
...PeopleFragment
#arguments(arg: $arg, arg2: $arg2)
#relay(mask: false)
}

the only way to fix it is like
query ChatRefetchContainerRefetchQuery(
$arg: ID!
$arg2: Boolean!
) {
Peoples #arguments(arg: $arg, arg2: $arg2) {
...PeopleFragment #relay(mask: false)
}
}

Related

Apollo server, GraphQL and Sequelize - how to put raw data into a GraphQL Schema Response

After scouring the internet for a specific example, I am throwing in the towel and asking for some help.
I am using Apollo server, GraphQL and Sequelize, and I am calling stored procedure that returns a record set created from two different tables. I am getting the data back, but I cannot figure out how to put the result into a GraphQL schema response.
Here is the code in my resolver:
async functionName(_, {input}, {user = null}) {
if (!user) {
throw new AuthenticationError('You must login to use this function');
}
const {record_id} = input;
const result = await DBService.query(
'Call sp_JoinTwoTables_Select(:id)',
{
model: FooModel,
mapToModel: true,
raw: true,
replacements: {id: record_id},
type: QueryTypes.SELECT
}
);
console.log('functionName.result');
console.log(result); // Getting results
return result;
}
Here is the code in my schema:
const {gql} = require('apollo-server-express');
module.exports = gql`
type Foo {
id: Int!
foo_name: String!
date_created: String!
date_modified: String!
}
extend type Mutation {
functionName(input: fooInput!): fooResponse!
}
input fooInput {
id: Int!
}
type fooResponse {
tree: [fooSchemaForBothTables!]
}
type fooSchemaForBothTables {
id: Int!
foo_name: String!
column_from_second_table: Int!
}
`;
Since there is no table in the database, I created a simple object. When that failed I tried a sequelized model object, but that also is failing. Here is this code:
module.exports = {FooModel: {
id: 0,
fooName: '',
column_from_second_table: 0
}};
The output I am getting is (not a 2d array as I thought):
Executing (default): Call sp_CommunityHierarchy_Select(9)
selectHierarchyTree.result
[
{
'0': {
community_id: 1,
community_name: 'Cars',
level_from_apex: null,
parent_id: null
},
'1': {
community_id: 8,
community_name: 'Chevy',
level_from_apex: 2,
parent_id: 1
},
'2': {
community_id: 9,
community_name: 'Suburban',
level_from_apex: 3,
parent_id: 8
},
meta: [ [ColumnDef], [ColumnDef], [ColumnDef], [ColumnDef] ]
},
{ affectedRows: 6, insertId: 0, warningStatus: 0 }
]
Your 'raw' DB result:
is an array;
1st element is an object with records/items encoded as index-named properties;
Your required mutation (why not a query type!?) response should tree: [fooSchemaForBothTables!] - object with tree named property (really required additional nesting level?) with an array of fooSchemaForBothTables-shaped objects as values:
{
tree: [
{
id: 1,
foo_name: 'Cars`,
column_from_second_table: 'whatever`,
},
{
id: 2,
foo_name: 'Chevy`,
column_from_second_table: 'whatever`,
}
]
}
Your job is to convert DB response into the required mutation result shape.
Hint: You can hardcode this DB result (some input const) in a side project (codesandbox) and write some conversion fn. When ready use it in this resolver.
You can also search for some more reliable sequelize (leave graphql alone for a moment) tutorials with 'more working' model mapping.
Next step?
If it is a tree then why not return this as a tree structure - nested nodes/types?

relay modern run RefetchContainer only manually

I still don't have much experience with relay modern and am trying to implement a search.
For this I use a "RefetchContainer":
export default createRefetchContainer(
SearchComponent,
{
base: graphql`
fragment SearchComponent_base on Base
#argumentDefinitions(
input: {type: "FireSearchInput!" defaultValue: {page: 0,queryString:""}}
)
{
search(input: $input){
total
...SearchResult_searchResult
}
}
`
},
graphql`
query SearchComponentRefetchQuery($input: FireSearchInput!) {
...SearchComponent_base #arguments(input: $input)
}
`
)
The problem is only that the query is already execute when you start the app, without an input is made.
Is it possible to suppress the automatic query and execute it only with the command this.props.relay.refetch?
the solution is to simply use a QueryRenderer:
<QueryRenderer
environment={environment}
query={graphql`
query SearchComponent($input: FireSearchInput!) {
search(input: $input){
total
...SearchResult_searchResult
}
}
`}
variables={{
input: {///my input}
}}

Refetch Container with two independent data sets

I have a component that has two 'independent' datasets, in that refetching argument a changes field A and refetching argument b changes field B.
export default createRefetchContainer(
Component,
{
a: graphql`
fragment Comp_a on Query #argumentDefinitions(
a: { type: "String!", defaultValue: "" },
) {
A(a: $a) {
name
}
}
`,
b: graphql`
fragment MainList_repo on Query #argumentDefinitions(
b: { type: "String!", defaultValue: "" }
) {
B(b: $b) {
name
}
}
`
},
{
a: graphql`
query CompRefetchQuery($a: String!) {
...Comp_a #arguments(a: $a)
}
`,
b: graphql`
query CompRefetchQuery($b: String!) {
...Comp_b #arguments(b: $b)
}
`
}
)
There is no such example in relay docs, and I just inferred this from fragment containers. The problem is calling
props.relay.refetch(vars => ({ data }), null)
results in a RelayModernGraphQLTag: Expected an operation, got{}. error (reporting refetch itself as the call site).
Is there a way to create two 'refetch' subsets like this in relay? Or do I need to create two refetch containers and nest them?

Capturing the same variable in one of multiple closures

I have two closures that capture the same Vec and I don't know how to write this in idiomatic Rust:
use std::error;
fn get_token -> Box<Vec<u8>>() {...}
fn do_stuff(file: &str) -> std::io::Result<i32> {...}
fn do_other_stuff(a: &str, a: &str) -> std::io::Result<i32> {...}
enum MyError {
IoError { token: Vec<u8>, reason: String ),
}
fn consumer() -> Result<MyError, ()> {
let token = get_token();
try!(do_stuff("a")
.map_err(|e| MyError::IoError { token: token, reason: "foo".to_str() }));
try!(do_other_stuff("b", "c")
.map_err(|e| MyError::IoError { token: token, reason: "bar".to_str() }));
}
I could replace the map_err calls with match expressions but I really am stumped by this: how do I pass a Vec to multiple closures?
First of all: Please make sure to provide an MCVE in the future, it's not fun to have to fix syntax errors before being able to reproduce your problem: http://is.gd/tXr7WK
Rust does not know that the only way the second closure can run, is if the first closure did not run and will never run. You can either wait for the let/else RFC to be accepted, implemented and stabilized, or you can create your error in steps, first create an inner closure that does all the operations for that one error kind without using up the token, then run the closure, then map the error to your custom error type.
|| -> _ {
try!(do_stuff("a").map_err(|e| ("foo".to_owned(), e)));
try!(do_other_stuff("b","c").map_err(|e| ("bar".to_owned(), e)));
Ok(())
} ().map_err(|(reason, e)| MyError::IoError{ token: token, reason: reason })
There's something weird going on where the closure requires us to specify that it returns something with -> _, but I'm not sure what it is.
Much more straightforward is to just not use try! or closures:
if let Err(e) = do_stuff("a") {
return Err(MyError::IoError{token: token, reason: "foo".to_owned()});
}
if let Err(e) = do_other_stuff("b", "c") {
return Err(MyError::IoError{token: token, reason: "bar".to_owned()});
}
This lets Rust perform straightforward analysis like you want it to, and is much more readable than dancing through hoops.
You can use and_then() combinator to avoid additional closure:
try!(do_stuff("a").map_err(|_| "foo" )
.and_then(|_|
do_other_stuff("b","c").map_err(|_| "bar")
)
.map_err(|e| MyError::IoError{token:token,reason:e.into()})
);

breeze.debug.js javascript error

I have been building a SPA with breeze and WebAPI (starting with John Papa's sample) for a couple of months. A couple of days ago on my Windows 8 VS2012 internal IE browser started giving me javascript errors in breeze.debug.js.
JavaScript critical error at line 4663, column 13 in //http://localhost:50033/Script/breeze.debug.js
SCRIPT1028: Expected identifier, string or number
I went back to my other development machine, Windows 7 with VS2012 and it does not give the error. The code between the two machines is identical. I use Azure TFS to sync the code.
The error occurs at the closing });
function convertFromODataEntityType(odataEntityType, schema, metadataStore, serviceName) {
var shortName = odataEntityType.name;
var namespace = translateNamespace(schema, schema.namespace);
var entityType = new EntityType({
shortName: shortName,
namespace: namespace,
}); <==== line 4663
When I remove the comma after namespace, the error goes away but errors out again in another spot on line 6911.
day: { fn: function(source) { return source.day;}, dataType: "Number" },
month: { fn: function(source) { return source.month; }, dataType: "Number" },
year: { fn: function(source) { return source.year; }, dataType: "Number"},
}; <========= line 6911
Remove the comma on the line above and it errors out on line 1271
Unhandled exception at line 1271, column 17 in http://localhost:50033/Scripts/breeze.debug.js
0x800a01b6 - JavaScript runtime error: Object doesn't support property or method 'some'
at this code:
function compile(self) {
if (!self._compiledFn) {
// clear off last one if null
if (self._fns[self._fns.length - 1] == null) {
self._fns.pop();
}
if (self._fns.length === 0) {
return undefined;
}
self._compiledFn = function (that, v) {
return that._fns.some(function (fn) {
return fn(that, v);
});
};
};
return self._compiledFn;
}
Has anyone else seen this behavior?
Just a guess, but check that you are not running IE in 'compatability' mode. The 'some' method is part of the ES5 standard and is not available in 'compatability' mode.
To avoid compatability mode issues with IE browsers, we highly recommend adding the following to your HTML header:
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"/>
I've run into it too. In fact, I often do this to myself, especially when deleting or reordering the last k/v pair during development.
While IE10 and other browsers are more forgiving, we should eliminate trailing commas on our hashmap object key/value lists ... and will do so.
FWIW, the following regex expression finds them all
,(\s*)\}\)
and the following regex substitution pattern fixes them (preserving whitespace):
$1\}\)

Resources