From 28a82e288a9d4dd0d7ecb14f07cd3a64a696e432 Mon Sep 17 00:00:00 2001
From: Erik Lumme <erik@vaadin.com>
Date: Tue, 12 Sep 2017 11:52:14 +0300
Subject: Migrate ExposingServerSideAPIToJavaScript

---
 .../ExposingServerSideAPIToJavaScript.asciidoc     | 134 +++++++++++++++++++++
 1 file changed, 134 insertions(+)
 create mode 100644 documentation/articles/ExposingServerSideAPIToJavaScript.asciidoc

(limited to 'documentation/articles/ExposingServerSideAPIToJavaScript.asciidoc')

diff --git a/documentation/articles/ExposingServerSideAPIToJavaScript.asciidoc b/documentation/articles/ExposingServerSideAPIToJavaScript.asciidoc
new file mode 100644
index 0000000000..2f41d453a1
--- /dev/null
+++ b/documentation/articles/ExposingServerSideAPIToJavaScript.asciidoc
@@ -0,0 +1,134 @@
+[[exposing-server-side-api-to-javascript]]
+Exposing server-side API to JavaScript
+--------------------------------------
+
+The new JavaScript integration functionality will allow you to easily
+publish methods that can be called with JavaScript on the client side.
+In effect, you can publish a JavaScript API for your application.
+Although you will probably not find yourself using this very often, it
+can be useful when integrating with JavaScript frameworks or embedding
+within legacy sites.
+
+Exposing a `notify()` method that takes a message and displays that as a
+notification can be done in one simple block in e.g `UI.init()`:
+
+[source,java]
+....
+JavaScript.getCurrent().addFunction("notify", new JavaScriptFunction() {
+  public void call(JSONArray arguments) throws JSONException {
+    Notification.show(arguments.getString(0));
+  }
+});
+....
+
+This will expose the `notify()`{empty}-method globally in the window object.
+Technically it's thus `window.notify()`, but you can call it by simply
+by `notify()`. Try entering `notify("Hey!")` into the Firebug or
+Developler Tools console, or `javascript:notify("Hey!")` into the
+address bar.
+
+You'll notice that this assumes there is a String in the first position
+of the array. Also, this will clutter the global namespace, which is
+generally not a good idea, unless you really have a specific need for
+that.
+
+Let's make a complete example with two arguments, some simple error
+handling, and namespacing:
+
+[source,java]
+....
+JavaScript.getCurrent().addFunction("com.example.api.notify",
+  new JavaScriptFunction() {
+    public void call(JSONArray arguments) throws JSONException {
+      try {
+        String caption = arguments.getString(0);
+        if (arguments.length() == 1) {
+            // only caption
+            Notification.show(caption);
+        } else {
+            // type should be in [1]
+            Notification.show(caption,
+                Type.values()[arguments.getInt(1)]);
+        }
+      } catch (JSONException e) {
+        // We'll log in the console, you might not want to
+        JavaScript.getCurrent().execute(
+            "console.error('" + e.getMessage() + "')");
+      }
+    }
+  });
+}
+....
+
+Using the dotted notation for the method will automatically create those
+objects in the browser; you'll call this method like so:
+`com.example.api.notify("Hey!")`. You do not have to use a long name
+like this, though - it's up to you and your use-case.
+
+The second thing to notice is that we now wrapped the code in a
+try-catch, so that the wrong number or wrong types of arguments does not
+cause an ugly stacktrace in our server logs. Again, how you should react
+to erroneous use of your exposed API depends on your use-case. We'll log
+an error message to the browser console as an example.
+
+We're now accepting a second (integer) argument, and using that as
+_type_ for the `Notification`.
+
+Finally, we'll add a link that will call the function, and work as a
+_Bookmarklet_. You can drag the link to your bookmarks bar, and when you
+invoke it when viewing the application with our exposed `notify()`{empty}-method, you will be prompted for a message that will then be sent to
+the method. Here is the plain HTML code for creating such a link:
+
+[source,html]
+....
+<a href="javascript:(function(){com.example.api.notify(prompt('Message'),2);})();">Send message</a>
+....
+
+Here is the full source for our application:
+
+[source,java]
+....
+import org.json.JSONArray;
+import org.json.JSONException;
+import com.vaadin.server.ExternalResource;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.ui.JavaScript;
+import com.vaadin.ui.JavaScriptFunction;
+import com.vaadin.ui.Link;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.Notification.Type;
+import com.vaadin.ui.UI;
+
+public class JSAPIUI extends UI {
+  @Override
+  public void init(VaadinRequest request) {
+
+    JavaScript.getCurrent().addFunction("com.example.api.notify",
+        new JavaScriptFunction() {
+          public void call(JSONArray arguments) throws JSONException {
+            try {
+              String caption = arguments.getString(0);
+              if (arguments.length() == 1) {
+                // only caption
+                Notification.show(caption);
+              } else {
+                // type should be in [1]
+                Notification.show(caption,
+                    Type.values()[arguments.getInt(1)]);
+              }
+            } catch (JSONException e) {
+              // We'll log in the console, you might not want to
+              JavaScript.getCurrent().execute(
+                  "console.error('" + e.getMessage() + "')");
+            }
+          }
+        });
+
+
+    setContent(new Link(
+        "Send message",
+        new ExternalResource(
+            "javascript:(function(){com.example.api.notify(prompt('Message'),2);})();")));
+  }
+}
+....
-- 
cgit v1.2.3

