Understanding onComplete from useMutation in Apollo - apollo-client

Reading useMutation api documentation, a question came to my mind.
onCompleted is executed no matter the result of the mutation? then when I access the information returned by the mutation with onComplete: (data) => // make something with data, data can also contain errors if the mutation returned some error from the server and I still need to validate that data has not contain errors?

According to the official doc:
onCompleted is a callback function that's called when your mutation successfully completes with zero errors (or if errorPolicy is ignore and partial data is returned).
This function is passed the mutation's result data.

Related

Is it possible to map a subscription parameter to an array at the mutation output?

I have a theoretical question. As I know subscription parameters must exist as a field in the returning type of the mutation. This means that the type of parameter must also match the type of the field in the returning object of the mutation. Am I right? Suppose I get an array with channels ids in the mutation response. I only send one channel id as a parameter in the subscription. Is it possible to map a subscription parameter to an array at the mutation output? If the channel id exists in the array (field channelsIds), the subscription must work. Is it possible to write this logic in the scheme itself, or is it technically impossible?
GraphQL schema:
schema {
mutation: Mutation
subscription: Subscription
}
type Mutation {
testMutation(input: TestMutationInput): TestMutationOutput
}
type TestMutationOutput {
channelsIds: [String!]!
userId: String!
userEmail: String
userPhoneNumber: String
}
type Subscription {
watchTestMutation(channelId: String!): TestMutationOutput
#aws_subscribe(mutations: ["testMutation"])
}
If I understand you correctly you want to filter based on if the mutation's returned value is in an array that is passed as an argument to the subscription. Sorry to say that is not possible at this time. Subscription filters only evaluate to true or false and cannot accommodate any logic other than that.
At the end of October 2020, I contacted AWS support for advice on this issue. I think this answer may be useful to someone, so I post their answer.
Please allow me to inform you that the use-case that you have
mentioned in the case is currently not possible via AppSync. I
understand that the lack of the feature may be causing inconvenience.
There is an internal feature request already with the AppSync team to
incorporate this feature and I have added a +1 on your behalf. It is
worth noting, that once this feature request is with the team, it will
be up to the team as to if/when this potential infrastructure feature
is implemented, and because of the limited visibility into the
progress of internal development processes, I won’t be able to provide
an ETA regarding its release. I would request you to keep an eye on
the what's new page or the AWS Blogs as all new feature requests and
enhancements are posted there[1-3].
However we can suggest a couple of workarounds in this case:
Filter the required fields on client side itself after receiving the values on the client-side from AppSync.
If the values to be filtered are very limited we can use a fake mutation made with the help of a resolver mapped to “None” Data
source. In this flow, we would create a lambda function that uses a
DynamoDB stream as the trigger. The Lambda function is triggered
whenever there's an update to the DynamoDB table.

We can then include logic in the Lambda function to filter the
required fields and perform a mutation to AppSync. In AppSync, the
mutation which was called by lambda would configured using a resolver
mapped to a “None” Data source. The None data source type passes the
request mapping template directly to the response mapping template.
And when we subscribe to this mutation, we will directly get the
filtered data from Lambda that was used to call this mutation. Please
refer to [4] for a step-by-step description of this process.
But please note that this workaround is cumbersome and would require a lot of changes if the required field values keep changing. Workaround 1(handling it on the client-side) is usually the preferred way to handle this use-case.
Resources:
[1] https://blogs.amazon.com/
[2] https://aws.amazon.com/new/
[3] https://aws.amazon.com/releasenotes/
[4] https://aws.amazon.com/premiumsupport/knowledge-center/appsync-notify-subscribers-real-time/

How to always return Graphql field?

I would like to always return a field when certain requests are made so that additional actions can be performed by the client.
For example if user registration has been successful I want to show flash message. But it has to be handled by the backend and not the front end.
I could "require" clients to always request specific field that would hold the needed information but it could be easily overlooked so I'd like to return data whenever needed.
Is this possible?
There is nothing in the GraphQL spec that allows particular fields to be required in the same sense that arguments can be required. This can be handled inside the resolver, however. For example, if you have a query called getFoos, and you want to require the clients to always request the field foo when fetching that query, your resolver for getFoos could look like this:
function (obj, args, ctx, info) {
const fields = info.fieldNodes[0].selectionSet.selections.filter(s => s.name.value)
if (!fields.includes('foo')) return Promise.reject(new Error('Missing field foo!'))
// continue resolving the query as normal
}
Each resolver takes as its fourth parameter an info object that contains detailed information about the request, including what fields were requested. So inside your resolver, just verify that the field was included, and if it's missing, return a rejected Promise instead. This will cause your query to fail anytime that particular field is missing.

Does Parse.Cloud.beforeRead exist is some form?

In Parse there is something called:
Parse.Cloud.beforeSave
I wonder if there is something to play the role of a:
Parse.Cloud.beforeRead
I need a way to control what is going to be returned to the user when a request is made to the DB.
In particular in certain circomstances, depending on information on the server, I want to force blank fields in the result of the DB request made by the user. Any standard way to do this?
There is no Parse.Cloud.beforeRead kind of function supported by Parse.
Instead, you can define a custom cloud function using
Parse.Cloud.define('readObjects', function(request, response) {...} );
that returns array of objects. This function will act as a wrapper over the Parse query.
Then, your client apps should be calling this cloud function to fetch objects rather than direct Parse.Query requests.

Ember.js REST Ajax Success and Error

I'd like to know what the success and error do in the Ember.js RESTAdapter's ajax function.
hash.success = function(json) {
Ember.run(null, resolve, json);
};
hash.error = function(jqXHR, textStatus, errorThrown) {
Ember.run(null, reject, jqXHR);
};
I know hash is the data sent through AJAX, but what role do success and error play? I assume they'd be run based on a successful or erroneous AJAX response, right? They're set before the AJAX is called, as callbacks? How do they work?
but what role do success and error play? I assume they'd be run based on a successful or erroneous AJAX response, right?
Right, since ember uses jQuery under the hood the functions mentioned are just plain jQuery methods.
They're set before the AJAX is called, as callbacks? How do they work?
As for the functions itself, see this info taken from the jQuery official docs:
error callback option is invoked, if the request fails. It receives the jqXHR, a string indicating the error type, and an exception object if applicable. Some built-in errors will provide a string as the exception object: "abort", "timeout", "No Transport".
success callback option is invoked, if the request succeeds. It receives the returned data, a string containing the success code, and the jqXHR object.
I should also mention that the success callback is in recently jQuery version being replaced with done and is marked as deprecated as noted here:
Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are deprecated as of jQuery 1.8. To prepare your code for their eventual removal, use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.
But don't worry, because I guess until jQuery removes this methods completely the ember team has surely catched up with the new callback versions.
And finally if you where wondering what the call to Ember.run does you can have a look here. But basically it ensures that the passed target and method are run inside of a RunLoop, ensuring also any deferred actions like bindings and views updates, this are flushed at the end. This SO answer on the Runloop is also very informative.
Hope it helps.

Ajax security: how to be sure that data sent back to the server is generated by my code?

I apologize in advance if this question sounds naive to you.
The problem is this: I have this function and I want the callback function to send the "response" back to my server via Ajax.
function FbInviteFriends()
{
FB.ui({
method: 'apprequests',
message: 'Hi! Join me on XXXXXXX'
},
//My callback function
function(response){
//Send response to my server
}
Is there a way to check that the response I'm going to receive server-side is actually the same I got when the callback function is called and that the response hasn't been modified on the client-side by the user?
Thanks!
There's a few ways, but all of them fall on the same principle - you can never know for sure, so treat it with a grain of salt and validate.
That said, one way to put at least one usage constraint may look like this:
Page accessed: Generate a token GUID. Render it at the client.
Store in the user session the moment it was created/used, together with user profile.
Client appends the token to all Ajax posts.
Token is validated at the server; must match SessionID, user profile (if any), and maximum usage timeout.
If it fails validation, abort the operation.

Resources