Pulling date data with onclick var - google-app-maker

I am trying to setup a send to email on click with app maker, one of my objects that sends is the date. I have this code for pulling that data:
var todayDate = widget.parent.parent.descendants.Field.value
I then get this error when testing the date data entries:
Failed due to illegal value in property: 4
at (unknown)
at (unknown)
at Inbound_Call.Container.Form1.Form1Header.Form1Spinner.visible:-1:132
at (unknown)
at (unknown)
at (unknown)
at Inbound_Call.Container.Form1.Form1Footer.Form1SubmitButton.onClick:7:40

Assuming that you are trying to make server call to send an email, smth like this:
google.script.run.myServerFunction(myDate, otherParam1, otherParam2);
I can suggest that call fails due to App Script parameters constraints:
Legal parameters are JavaScript primitives like a Number, Boolean, String, or null, as well as JavaScript objects and arrays that are composed of primitives, objects, and arrays. A form element within the page is also legal as a parameter, but it must be the function’s only parameter. Requests fail if you attempt to pass a Date, Function, DOM element besides a form, or other prohibited type, including prohibited types inside objects or arrays. Objects that create circular references will also fail, and undefined fields within arrays become null....

Related

Accessing pubsublite message attributes in beam pipeline - Java

We have been using PubSubLite in our Go program without any issues and I just started using the Java library with Beam.
Using the PubSubLite IO, we get PCollection of SequencedMessage specifically: https://cloud.google.com/java/docs/reference/google-cloud-pubsublite/latest/com.google.cloud.pubsublite.proto.SequencedMessage
Now, from it I can get the data by doing something like:
message.getMessage().getData().toByteArray()
and then doing the normal conversion.
But for attributes, I cannot seem to get it correctly, just the value. In Go, I could do:
msg.Attributes["attrKey"]
but when I do:
message.getMessage().getAttributesMap().get("attrKey")
I am getting an Object which I cannot seem to convert to just string value of it. As far as I understand, it returns a Map<String, AttributeValues> and they all seem to be just wrapper over the internal protobuf. Also, Map is an interface so how do I get to the actual implementation to get the underlying value of each of the attribute.
The SequencedMessage attributes represent a multimap of string to bytes, not a map of string to string like in standard Pub/Sub. In the go client, by default the client will error if there are multiple values for a given key or if any of the values is not valid UTF-8, and thus presents a map[string]string interface.
When you call message.getMessage().getAttributesMap().get("attrKey"), you have a value of type AttributeValues which is a holder for a list of ByteStrings. To convert this to a single String, you would need to throw if the list is not of length 1, then call toStringUtf8 on the byte string element with index 0.
If you wish to interact with the standard Pub/Sub message format like you would in go, you can convert to this format by doing:
import org.apache.beam.sdk.io.gcp.pubsub.PubsubMessage;
import org.apache.beam.sdk.io.gcp.pubsublite.CloudPubsubTransforms;
PCollection<SequencedMessage> messages = ...
PCollection<PubsubMessage> transformed = messages.apply(CloudPubsubTransforms.toCloudPubsubMessages());

Google Tag Manager - Parse Dynamic Data Layer Variable

I want to parse a 'pushed' data layer string. I intend to use it to track click events and setup the appropiate funnels in Google Analytics, it looks as follows: products.view.19|view recent product|19
The first part (products.view.19) is the unique page identifier.
The second part (view recent product) is the action.
The last part is (19) is the action identifier, this way actions may be grouped and compared more easily.
So I did the following, I first created a trigger (it fires when a link has the tag 'data-trackclick' in it) which pushes the data value to a variable (variable for datalayer). However, now I want to split that variable in to 3 new variables, as described above. I selected 'javascript macro' for this but somehow it returns 'undefined'. The macro looks as follows:
function() {
var data = {{TrackClickData}};
var pieces = data.split('|');
if (pieces[0].length()) {
return pieces[0];
} else {
return data;
}
}
Obviously this didnt work since it would only run on the initial load and not (like I thought) when the macro was requested, so it should somehow be fired on the 'click' and then set the variables accordingly.
Is this possible to do? Or do I really have to add the dataLayer.push() in script tags?
A few things:
.length() is wrong, the property for array length is .length without the ()
if it exists, pieces[0] is not an array, then .length would return the string length, see How do you check for an empty string in JavaScript? for more standard way of checking for empty strings
Is this possible to do? There's virtually nothing you can't do with GTM, since you can write JavaScript code, you can do whathever you code allows you to do, and splitting a string to use parts of it as variables is certainly within the realm of possibilities.
My advise is to make your code work outside GTM first (eg test it in the browser console), then once it's all working, port it to GTM.

What is the use case of firebase-queue sanitize?

I am experimenting with firebase-queue. I saw the option for sanitizing. It's described in the doc as
sanitize - specifies whether the data object passed to the processing
function is sanitized of internal keys reserved for use by the queue.
Defaults to true.
What does it mean?
I am getting an error for not specifying { sanitize : false }
When the sanitize option is set, the queue sanitizes (or cleans) the input provided to the processing function so that it resembles that which the original client placed onto the queue, and doesn't contain any of the keys added by the implementation of the queue itself.
If, however, you rely on a key (usually the keys starting with an underscore, e.g. _id) that is added by the queue, and not the original client, you need to set sanitize: false so those keys are returned to your function and they're not undefined.
You can clearly see the difference with a simple processing function that just performs a console.log(data).
A quick note about why these keys are removed by default: Reading or writing directly to the location (as it looks like you're perhaps doing, by passing undefined into the client SDK child() method instead of data._id) is generally a bad idea from within the worker itself as writes performed directly are not guarded by the extensive transaction logic in the queue to prevent race conditions. If you can isolate the work to taking input from the provided data field, and returning outputs to the resolve() function, you'll likely have a better time scaling up your queue.

Can I pass an array to a function using the ... rest* construction?

I'm making multiple similar calls with similar results to one remote object. Because these calls are so similar and very changeable, I've been keeping the name of the remote method in a config file, and when I need to make the call I use getOperation() on the remote object, and call send() on the operation object. However, the requirements have changed so that not all of the calls will have the same number of parameters.
Because send uses ..., will I be able to continue using the same formation and pass an array, or will send() treat that as passing one argument of type array?
The Operation class also has an "arguments" property that you can use. That way you can prefill it before calling send(). The send() method then requires not extra arguments.
var operation:Operation = Operation(remoteObject.getOperation(methodName));
operation.arguments = parameters;
var token:AsyncToken = operation.send();
var responder:Responder = new Responder(resultHandler, faultHandler);
token.addResponder(responder);
you can use the ...rest
that will give you an array with a bunch of objects. I would recommend tat you make the first item [0] always the ID. This ID should identify either the sender or the type of object being passed. you can easily do a switch/case for each type of item. You could also do a more sophisticated way of dealing with this, but this should work.

When should I call javax.jdo.Query.close(Object)?

I'm trying to understand when I should call Query.close(Object) or Query.closeAll();
From the docs I see that it will "close a query result" and "release all resources associated with it," but what does "close" mean? Does it mean I can't use objects that I get out of a Query after I've called close on them?
I ask because I'm trying to compartmentalize my code with functions like getUser(id), which will create a Query, fetch the User, and destroy the query. If I have to keep the Query around just to access the User, then I can't really do that compartmentalization.
What happens if I don't call close on an object? Will it get collected as garbage? Will I be able to access that object later?
Please let me know if I can further specify my question somehow.
You can't use the query results since you closed them (i.e the List object you got back from query.execute). You can access the objects in the results ... if you copied them to your own List, or made references to them in your code. Failure to call close can leak memory
When your query method returns a single object it is easy to simply close the query before returning the single object.
On the other hand, when your query method returns a collection the query method itself can not close the query before returning the result because the query needs to stay open while the caller is iterating through the results.
This puts the responsibility for closing a query that returns a collection on the caller and can introduce leaks if the caller neglects to close the query - I thought there must be a safer way and there is!
Guido, a long time DataNucleus user, created a 'auto closing' collection facade that wraps the collection returned by JDO's Query.execute method. Usage is extremely simple: Wrap the query result inside an instance of the auto closing collection object:
Instead of returning the Query result set like this:
return q.execute();
simply return an 'auto closing' wrapped version of it:
return new JDOQueryResultCollection(q, q.execute());
To the caller it appears like any other Collection but the wrapper keeps a reference to the query that created the collection result and auto closes it when the wrapper is disposed of by the GC.
Guido kindly gave us permission to include his clever auto closing code in our open source exPOJO library. The auto closing classes are completely independent of exPOJO and can be used in isolation. The classes of interest are in the expojo_jdo*.jar file that can be downloaded from:
http://www.expojo.com/
JDOQueryResultCollection is the only class used directly but it does have a few supporting classes.
Simply add the jar to your project and import com.sas.framework.expojo.jdo.JDOQueryResultCollection into any Java file that includes query methods that return results as a collection.
Alternatively you can extract the source files from the jar and include them in your project: They are:
JDOQueryResultCollection.java
Disposable.java
AutoCloseQueryIterator.java
ReadonlyIterator.java

Resources