Skip to content

Commit

Permalink
fix(api): do not include null values in ModelMutations.create (#2504)
Browse files Browse the repository at this point in the history
  • Loading branch information
Travis Sheppard committed Jan 12, 2023
1 parent 393ea2c commit d3795d7
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,10 @@ class GraphQLRequestFactory {
///
/// When the model has a parent via a belongsTo, the id from the parent is added
/// as a field similar to "blogID" where the value is `post.blog.id`.
Map<String, dynamic> buildInputVariableForMutations(Model model) {
Map<String, dynamic> buildInputVariableForMutations(
Model model, {
required GraphQLRequestOperation operation,
}) {
final schema =
getModelSchemaByModelName(model.getInstanceType().modelName(), null);
final modelJson = model.toJson();
Expand All @@ -303,10 +306,17 @@ class GraphQLRequestFactory {
}
}

// Remove any relational fields or readonly.
// Remove some fields from input.
final fieldsToRemove = schema.fields!.entries
.where(
(entry) => entry.value.association != null || entry.value.isReadOnly,
(entry) =>
// relational fields
entry.value.association != null ||
// read-only
entry.value.isReadOnly ||
// null values on create operations
(operation == GraphQLRequestOperation.create &&
modelJson[entry.value.name] == null),
)
.map((entry) => entry.key)
.toSet();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ class ModelMutationsFactory extends ModelMutationsInterface {
APIAuthorizationType? authorizationMode,
Map<String, String>? headers,
}) {
final input =
GraphQLRequestFactory.instance.buildInputVariableForMutations(model);
final input = GraphQLRequestFactory.instance.buildInputVariableForMutations(
model,
operation: GraphQLRequestOperation.create,
);
// Does not use buildVariablesForMutationRequest because creations don't have conditions.
final variables = {'input': input};

Expand Down Expand Up @@ -96,8 +98,10 @@ class ModelMutationsFactory extends ModelMutationsInterface {
}) {
final condition = GraphQLRequestFactory.instance
.queryPredicateToGraphQLFilter(where, model.getInstanceType());
final input =
GraphQLRequestFactory.instance.buildInputVariableForMutations(model);
final input = GraphQLRequestFactory.instance.buildInputVariableForMutations(
model,
operation: GraphQLRequestOperation.update,
);

final variables = GraphQLRequestFactory.instance
.buildVariablesForMutationRequest(input: input, condition: condition);
Expand Down
16 changes: 12 additions & 4 deletions packages/api/amplify_api/test/graphql_helpers_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,6 @@ void main() {
'id': id,
'name': name,
'createdAt': time,
'file': null,
'files': null
}
};
const expectedDoc =
Expand All @@ -393,6 +391,18 @@ void main() {
expect(req.decodePath, 'createBlog');
});

test(
'ModelMutations.create() should not include null fields in input variable',
() {
const name = 'Test Blog';

final Blog blog = Blog(name: name);
final GraphQLRequest<Blog> req = ModelMutations.create<Blog>(blog);
final inputVariable = req.variables['input'] as Map<String, dynamic>;

expect(inputVariable.containsKey('file'), isFalse);
});

test(
'ModelMutations.create() should build a valid request for a model with a parent',
() {
Expand All @@ -413,8 +423,6 @@ void main() {
'id': postId,
'title': title,
'rating': rating,
'created': null,
'likeCount': null,
'blogID': blogId
}
};
Expand Down

0 comments on commit d3795d7

Please sign in to comment.