React-admin: ra-data-graphql-simple: problem GET_MANY_REFERENCE in buildVariables.js

Created on 26 Nov 2018  ·  13Comments  ·  Source: marmelab/react-admin

Hi.

export const  UserEdit = props => {
    return (
        <Edit {...props}>
            <SimpleForm>
                <DisabledInput source="id" />
                <TextInput source="name" />
                <ReferenceManyField
                    reference="Customer"
                    target="userId"
                >
                    <Datagrid>
                        <TextField source="organizationName" />
                    </Datagrid>
                </ReferenceManyField>
            </SimpleForm>
        </Edit>
    );
}

It was expected that the record would be returned as in the documentation.

The query filter gets an object in the object, which prevents you from working further.
expected filter:
variables: {filter: {userId:"cjoa0w1z5005y0b91ka78ug3r"}}

Here's what gets into Request payload:

{operationName: "allCustomers", variables: {filter: {id: {id: "cjoa0w1z5005y0b91ka78ug3r"}}},…}
operationName: "allCustomers"
query: "query allCustomers($filter: CustomerFilter) {↵  items: allCustomers(filter: $filter) {↵    id↵    type↵    organizationName↵    organizationInn↵    payment↵    __typename↵  }↵  total: _allCustomersMeta(filter: $filter) {↵    count↵    __typename↵  }↵}↵"
variables: {filter: {userId: {id: "cjoa0w1z5005y0b91ka78ug3r"}}}
filter: {userId: {id: "cjoa0w1z5005y0b91ka78ug3r"}}
userId: {id: "cjoa0w1z5005y0b91ka78ug3r"}
id: "cjoa0w1z5005y0b91ka78ug3r"

the response from the server:

operationName: null
link.js:48
variables:
link.js:49
{
link.js:50
  "_v0_where": {
    "AND": [
      {
        "userId_contains": "[object Object]"
      }
    ]
  },
  "_v1_orderBy": "id_ASC"
}

  • React-admin version: 2.4.2
  • Last version that did not exhibit the issue (if applicable):
  • React version:16.5.2
  • Browser: Chrome 70.0.3538.110
  • Use: ra-data-graphql-simple
bug

Most helpful comment

Let's try a poll :)

All 13 comments

I'm sorry, I don't understand your issue.

It was expected that the record would be returned as in the documentation.

Which record? According to which part of the documentation?

The query filter gets an object in the object, which prevents you from working further.

What?

Here's what gets into Request payload

I understand you're using a GraphQL dataProvider, is that right? Which one? Could the problem come from there?

As for the request payload snippet, either it's incomplete, or it's badly formatted. I don't understand what's normal or not in there.

Please attach a CodeSandbox demonstrating the issue.

Documentation:

accepts a reference attribute, which specifies the resource to fetch for the related record. It also accepts a source attribute which define the field containing the value to look for in the target field of the referenced resource. By default this is the id of the resource (post.id in the previous example).

what was expected in the request:
{filter: {userId: "cjoa0w1z5005y0b91ka78ug3r"}}

what is actually in the request:
{filter: {userId: {id: "cjoa0w1z5005y0b91ka78ug3r"}}}

yes

Use: ra-data-graphql-simple

what ra-data-graphql-simple sends to the server:

operationName: null
link.js:48
variables:
link.js:49
{
link.js:50
"_v0_where": {
"AND": [
{
"userId_contains": "[object Object]"
}
]
},
"_v1_orderBy": "id_ASC"
}

because of "userId_contains": "[object Object]", the wrong response from the server.

As I understand it, ra-data-graphql-simple generates a filter for the query and it does it wrong.

What query filter for resource Customer is provided for such a component?

export const  UserEdit = props => {
    return (
        <Edit {...props}>
            <SimpleForm>
                <DisabledInput source="id" />
                <TextInput source="name" />
                <ReferenceManyField
                    reference="Customer"
                    target="userId"
                >
                    <Datagrid>
                        <TextField source="organizationName" />
                    </Datagrid>
                </ReferenceManyField>
            </SimpleForm>
        </Edit>
    );
}

Sorry, I can't add my GraphQL server to the CodeSandbox for demonstration.
I can attach files datamodel.graphql, schema.graphql, Query resolver if necessary.
For the React-admin server everything is standard, according to the documentation.

schema.graphql is created as specified here:
https://github.com/marmelab/react-admin/tree/master/packages/ra-data-graphql-simple
by the way, the PostFilter needs ids instead of id:

input PostFilter {
    q: String
    ids: ID
    title: String
    views: Int
    views_lt: Int
    views_lte: Int
    views_gt: Int
    views_gte: Int
    user_id: ID
}

Update:
I think you need to rename the topic. I found a solution.
The problem in the code:

...\ui-react-admin\node_modules\ra-data-graphql-simple\esm\buildVariables.js

export default (function (introspectionResults) {
    return function (resource, aorFetchType, params, queryType) {
        switch (aorFetchType) {
           ...
            case GET_MANY_REFERENCE:
                {
                    var parts = params.target.split('.');

                    return {
                        // filter: _defineProperty({}, parts[0], { id: params.id })
            filter: _defineProperty({}, parts[0], params.id)
                    };
                }
           ...
        }
    };
});

It solved my problem, but is it right?

I went further
Documentation:

By default, react-admin restricts the possible values to 25. You can change this limit by setting the perPage prop.


<ReferenceManyField perPage={10} reference="comments" target="post_id">
   ...
</ReferenceManyField>

By default, it orders the possible values by id desc. You can change this order by setting the sort prop (an object with field and order properties).

<ReferenceManyField sort={{ field: 'created_at', order: 'DESC' }} reference="comments" target="post_id">
   ...
</ReferenceManyField>

Also, you can filter the query used to populate the possible values. Use the filter prop for that.

<ReferenceManyField filter={{ is_published: true }} reference="comments" target="post_id">
   ...
</ReferenceManyField>

This request sends GET_LIST:
get_list

This request sends GET_MANY_REFERENCE:
get_many_ref

Accordingly, no sorting and filtering is performed.

changes:

...\ui-react-admin\node_modules\ra-data-graphql-simple\esm\buildVariables.js

export default (function (introspectionResults) {
    return function (resource, aorFetchType, params, queryType) {
        switch (aorFetchType) {
           ...
            case GET_MANY_REFERENCE:
                {
                    var parts = params.target.split('.');
                    var variables = buildGetListVariables(introspectionResults)(resource, aorFetchType, params, queryType);
                    variables.filter[parts[0]] = params.id

                    return variables;
                }
           ...
        }
    };
});

Can you make a PR to fix it?

I also ran into this issue and the fix worked. If there isn't a PR up in a couple of days I'll open one for it with the above fix.

@Redorb please feel free to open a PR

Any update on this?

Why the pull requests were closed?
So, is this a bug or only weird feature? :)

Let's try a poll :)

In addition, I was faced with the fact that in does not work with ra-data-graphql-simple (it is worth noting that everything works fine in DEMO).
So it turns out due to the fact that

C:...\ui-react-admin\node_modules\ra-data-graphql-simple\src

does not add all necessary parameters to query.
I made a crutch for myself:

export default (builtQuery, fetchType, resource, params) => {

    let result = {
        ...builtQuery,
        parseResponse : async function(response) {           

            return builtQuery.parseResponse(response);
        },
        variables: ((variables) => {
            if (fetchType == "GET_MANY_REFERENCE") {          

                return {
                    filter: variables.filter,
                    page: params.pagination.page-1,
                    perPage: params.pagination.perPage,
                    sortField: params.sort.field,
                    sortOrder: params.sort.order,
                }
            }

            return variables;
        })(builtQuery.variables),      
    }

    return result;
}

@christiaanwesterbeek I reopened the PR

Fixed by #2649

Was this page helpful?
0 / 5 - 0 ratings