GAS serverhandlers, what's the difference? - google-apps-script

What's the difference among
.createServerHandler,
.createServerClickHandler,
.createClickHandler
?
Thanks

referring to the doc method createServerClickHandler(functionName) - deprecated 2012-03-06
in favor of createServerHandler which creates the 'generic' server handler in the Uiinstance. The createClickHandler is one of many methods that defines the behavior of the handler : click/change/mouse/key... (see doc of the element you use) and the possible options will be different depending of the type of element.
Note that the autocomplete feature allows to see easily what handlers are available for each Ui element.

Also important to remember, a server side handler sends your request to the server to perform the and then sends the request response back to your application, which can have some latency.
If you have a task like disabling a button immediately after it is pressed, you can use a client handler which performs the operation inside the browser and doesn't have the latency that a server handler would have.
More info:
Handlers in general
https://developers.google.com/apps-script/guide_user_interfaces#UIUpdate
Client handlers
https://developers.google.com/apps-script/guide_user_interfaces#ClientHandlers
Hope that helps,
Ryan

Related

Restrict feathers service method to user for external but allow any queries for internal calls

I want to restrict calls to a Feathers service method for externals calls with associateCurrentUser.
I also want to allow the server to call this service method without restricting it.
The use case is that through this service then clients use a lock table, all clients can see all locks, and occasionally the server should clear out abandoned rows in this table. Row abandonment can happen on network failures etc. When the server removes data then the normal Feathers remove events should be emitted to the clients.
I would imagine that this should be a mix of associateCurrentUser and disallow hooks but I can't even begin to experiment with this as I don't see how it would be put together.
How would one implement this, please?
Update:
I found this answer User's permissions in feathers.js API from Daff which implies that if the hook's context.params.provider is null then the call is internal, otherwise external. Can anyone confirm if this is really so in all cases, please?
It seems to be so from my own tests but I don't know if there are any special cases out there that might come and bite me down the line.
If the call is external params.provider will be set to the transport that has been used (currently either rest, socketio or primus, documented here, here and here).
If called internally on the server there is not really any magic. It will be whatever you pass as params. If you pass nothing it will be undefined if you pass (or merge with) hook.params in a hook it will be the same as what the original method was called with.
// `params` is an empty object so `params.provider` will be `undefined`
app.service('messages').find({})
// `params.provider` will be `server`
app.service('messages').find({ provider: 'server' })
// `params.provider` will be whatever the original hook was called with
function(hook) {
hook.app.service('otherservice').find(hook.params);
}

Sending email notification on error using SSIS

I am currently implementing Send Email notification on error in my SSIS package. It currently works. Just want to check if this is the right way of doing it.
If you want to trigger your mail task when any error occurs, consider the "Event Handlers".
This SimpleTask article provides a very good overview of the event handlers
https://www.red-gate.com/simple-talk/sql/ssis/ssis-event-handlers-basics/
SSIS event handlers are the simplest means of turning an SSIS script into a reliable system that is auditable, reacts appropriately to error conditions, reports progress and allows instrumentation and monitoring your SSIS packages. They are easy to implement, and provide a great deal of flexibility.
Sample screen shot:
Using event handler provides some advantage - you need not connect each task's failure. The system will call your event handler for the error.
Also, note there are 2 event handlers of interest:
OnError
OnTaskFailed
https://learn.microsoft.com/en-us/sql/integration-services/integration-services-ssis-event-handlers
OnError event - This event is raised when an error occurs.
OnTaskFailed event - This event is raised by a task when it fails.
One thing to watch out for is that you event handler may be called multiple times depending on the number of errors.
I think there is no standard answer to this question. But here are some of the tips that I am be able to think of.
First, not very sure what kind of plain text you are trying to send out, if they do not have dynamic text body, you could put that send email task in the event handlers right to the Control flow, Data Flow... tab, and put that on error for specific tasks.
Second, I personally do not prefer to use Failure output, you may need to increase the number of MaximumErrorCount so that the package could executed successfully, but sometimes the real error might not be detected because together with error output, the total error numbers is still less than the threshold.
Third, if you are sending the same text, and you will schedule it as a job in SQL Server Agent, you could go to Notifications option page, set the Send Email, basically it will be informative.
Last but not least, the Send Mail task supports plain text only, not any formatting like email coded by html & CSS, if you need to take the formatting into consideration, that might not be your choice, you could use Script task using C# or creating html page by using XML statement from your SSMS and put into a stored procedure, then sent out the html by Database Mail, you will find this tool under Management folder in your SSMS.

How can I configure Polymer's platinum-sw-* to NOT cache one URL path?

How can I configure Polymer's platinum-sw-cache or platinum-sw-fetch to cache all URL paths except for /_api, which is the URL for Hoodie's API? I've configured a platinum-sw-fetch element to handle the /_api path, then platinum-sw-cache to handle the rest of the paths, as follows:
<platinum-sw-register auto-register
clients-claim
skip-waiting
on-service-worker-installed="displayInstalledToast">
<platinum-sw-import-script href="custom-fetch-handler.js"></platinum-sw-import-script>
<platinum-sw-fetch handler="HoodieAPIFetchHandler"
path="/_api(.*)"></platinum-sw-fetch>
<platinum-sw-cache default-cache-strategy="networkFirst"
precache-file="precache.json"/>
</platinum-sw-cache>
</platinum-sw-register>
custom-fetch-handler.js contains the following. Its intent is simply to return the results of the request the way the browser would if the service worker was not handling the request.
var HoodieAPIFetchHandler = function(request, values, options){
return fetch(request);
}
What doesn't seem to be working correctly is that after user 1 has signed in, then signed out, then user 2 signs in, then in Chrome Dev Tools' Network tab I can see that Hoodie regularly continues to make requests to BOTH users' API endpoints like the following:
http://localhost:3000/_api/?hoodieId=uw9rl3p
http://localhost:3000/_api/?hoodieId=noaothq
Instead, it should be making requests to only ONE of these API endpoints. In the Network tab, each of these URLs appears twice in a row, and in the "Size" column the first request says "(from ServiceWorker)," and the second request states the response size in bytes, in case that's relevant.
The other problem which seems related is that when I sign in as user 2 and submit a form, the app writes to user 1's database on the server side. This makes me think the problem is due to the app not being able to bypass the cache for the /_api route.
Should I not have used both platinum-sw-cache and platinum-sw-fetch within one platinum-sw-register element, since the docs state they are alternatives to each other?
In general, what you're doing should work, and it's a legitimate approach to take.
If there's an HTTP request made that matches a path defined in <platinum-sw-fetch>, then that custom handler will be used, and the default handler (in this case, the networkFirst implementation) won't run. The HTTP request can only be responded to once, so there's no chance of multiple handlers taking effect.
I ran some local samples and confirmed that my <platinum-sw-fetch> handler was properly intercepting requests. When debugging this locally, it's useful to either add in a console.log() within your custom handler and check for those logs via the chrome://serviceworker-internals Inspect interface, or to use the same interface to set some breakpoints within your handler.
What you're seeing in the Network tab of the controlled page is expected—the service worker's network interactions are logged there, whether they come from your custom HoodieAPIFetchHandler or the default networkFirst handler. The network interactions from the perspective of the controlled page are also logged—they don't always correspond one-to-one with the service worker's activity, so logging both does come in handy at times.
So I would recommend looking deeper into the reason why your application is making multiple requests. It's always tricky thinking about caching personalized resources, and there are several ways that you can get into trouble if you end up caching resources that are personalized for a different user. Take a look at the line of code that's firing off the second /_api/ request and see if it's coming from an cached resource that needs to be cleared when your users log out. <platinum-sw> uses the sw-toolbox library under the hood, and you can make use of its uncache() method directly within your custom handler scripts to perform cache maintenance.

apps-script: preventing multiple firing of handlers?

I'm seeing multiple submissions on a form, presumably because someone is double-clicking a submit button. Is there a good way to prevent this in GAS? I suppose I could set up a global variable via JSON, and use that to determine whether or not to execute the handler, but it seems a bit clunky.
Thanks.
create a client Handler that disables the submit button before the rest of your code is executed.
You can add a client handler anywhere you would add a server handler of any type, and it works entirely on the client without any server roundtrip.
See Serge insas comment below!

Spine.js - show "loading" message

Objective : To block the UI until the Ajax validation call returns. With some dialog or message.
The problem: How in a Spine/MVC way, am i supposed to append and them remove the HTML content on the top of current view?
Half-baked solution: Inside Controller->
Bind the model ajaxSuccess function to remove the message HTML, and append the "loading" message on Saving the Model object.
Any ideas,?
Thanks.
Quick answer: you should try to avoid it altogether. It's annoying for the user and against the core philosophy of spine.js.
http://spinejs.com/docs/introduction :
Core values:
[...]
Asynchronous interfaces - Too many JavaScript applications & frameworks don't take full advantage of the power of client-side rendering. End-users don't care if background requests to the server are pending, and don't want to see loading messages and spinners. Users want unblocked interfaces, and instant interaction. To enable this, Spine stores and renders everything client-side, communicating with the server asynchronously.
I understand that sometimes blocking just can't be avoided. In those cases I would follow this pattern:
In the controller:
Add blocking overlay html
Call model method that is asynchronous but needs blocking
Wait for model to emit an event that signals that the action is finished, eg. validationDone
In the model:
Write asynchronous method as usual
In both success and error handlers, emit the validationDone event