How to configure common data model across android and JS bridge? - javascript

I have a JS bridge in Android,
public class WebInterface {
Context mContext;
public WebInterface(Context c) { this.mContext = c;}
#JavascriptInterface
public void showAlert() {
Toast.makeText(mContext, "This is being called from the interface", Toast.LENGTH_SHORT).show();
}
}
I can set interface in my webView,
mWebView.addJavascriptInterface(WebInterface(this), "android");
This works fine for simple methods like showAlert() where the is no params when the params or the param is a simple string but when I need to pass a data model as a params while calling native functions from web app how can I bind data models? I am required to call implement a function with param of type custom data model.
public class WebInterface {
Context mContext;
public WebInterface(Context c) { this.mContext = c;}
#JavascriptInterface
public void showAlert() {
Toast.makeText(mContext, "This is being called from the interface", Toast.LENGTH_SHORT).show();
public void saveData(data: DataModel) { // DataModel is custom model
Toast.makeText(mContext, "Saving data model", Toast.LENGTH_SHORT).show();
}
}
How can I bind data model across native and web app. Is it possible using TypeScript? If so, how to configure? Is it only possible using plain json string as params? no any other way?

You should use the JSON string.
You can create another function receive the format you want, then JSON.stringify the object before pass to the function.
Javascript
function saveData(obj){
const json = JSON.stringify(obj);
Android.saveData(json);
}

Alternative away is used to JSON.parse(data)
javascript
function loadJson(obj) {
var jsonValue = JSON.parse(obj)
Android.saveData(jsonValue)
}

Related

How to inject javascript interface in android webview?

I am loading a page in webview in android. The page has an element(button) with the following code, NB:- It is a third party website and I have no control over the code shown here :-
<i class="icon close cardClose" role="button" title="Close recently linked screen" tabindex="0"></i>
I want to add a javascript interface as in the below method :-
private class myWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
view.addJavascriptInterface(new Object()
{
#JavascriptInterface
public void performClick() throws Exception
{
Toast.makeText(Activity.this, "Login clicked", Toast.LENGTH_LONG).show();
}
}, "login");
return true;
}
}
mWebView.setWebViewClient(new myWebViewClient());
But the problem is that webview source code says :-
* #param object the Java object to inject into this WebView's JavaScript
* context. Null values are ignored.
* #param name the name used to expose the object in JavaScript
*/
public void addJavascriptInterface(Object object, String name) {
checkThread();
mProvider.addJavascriptInterface(object, name);
}
The button doesnot seem to have an attribute named "name". Please throw some insight into the same if some one has knowledge.
I recommed you to use it this way
view.addJavascriptInterface(new JavaScriptInterfaceNew(getActivity(), this), "Android_Normal_Test");
and here JavaScriptInterfaceNew is your class name and Android_Normal_Test will be your object when you need to pass some event from webview to your activity class

How can I handle a dynamic viewModel in my controller?

In my controller, my create method takes a viewModel that inherits from DynamicObject. The reason is that I need static properties on the model, but I may also add things to it via JavaScript before I pass it to the controller.
So, I have:
public class MyViewModel: DynamicObject {
public string id {get;set;}
}
[HttpPost]
public IHttpActionResult Create(MyViewModel viewModel) {
// save to Db
}
From the JavaScript (using Angular), I've passed in this viewmodel:
var vm = { id: 1, name: "Jim"};
However, this does not work and is throwing me this error:
[{"PropertyName":null,"ErrorMessage":null,"ErrorCode":null,"AttemptedValue":null,"CustomState":null}]
I haven't found an example of what I'm trying to do, but I would think making an object dynamic would allow for this. What am I missing here?

How to bind a complex data structure to Spring Controller

I am trying to bind a complex data structure to my controller in spring mvc with javascript.
I have this ViewModel;
public class LibraryViewModel{
private String idLibrary;
private String nameLibrary;
private List<Box> listBox;
//Getters and setters
}
And this is the box's class:
List listBox;
public class Box{
private String idBox;
private List<String> booksNames;
//Getters and setters
}
What I want to do?
I want to do the form binding idLibrary and nameLibrary with a form in jsp
<form:form modelAttribute = "libraryVM" id="bestForm".../>
And listBox get a data injection like with a function made in JavaScript.
$('#bestForm').submit(function() {
completeListBoxInfo();
$('#organizacion').val(a);
});
But I allways get null mi List in mi controller but I get fine my idLibrary and nameLibrary attributes.
#RequestMapping("/save")
protected void guardar(#RequestParam("libraryFM") LibraryViewModel newLibrary) {
...
}
How can I bind the View Model object with the function result of completeListBoxInfo();
Kind regards.

Error : Third party action method not found

I am using one third party tool. I have inherited its controller with MVC controller
{
public class ReportController : ReportServiceBaseController
{
}
public abstract class ReportServiceBaseController : Controller
{
[HttpPost]
public JsonResult LoadDocumentInfo(LoadDocumentInfoRequest request);
[HttpPost]
public JsonResult LoadDocumentMapInfo(LoadDocumentMapInfoRequest request);
}
}
When I make call to "LoadDocumentInfo" method it give an error of not found.
Please help.
you use ReportController to call LoadDocumentInfo method ,but you have not implement this method in Controller ,so i think first you have to implement it in your controller and than try to call that method.

Pass element/function handler to gwt function

I'm using GWT to create a client-side only library. I'm using JSNI to call functions is Java from JS. The issue is I'm trying to pass in an element or a function handler and nothing seems to be happening. I don't get an exceptions from GWT or js. Here's my JSNI function with the bridge.
public static String testMe(Object obj)
{
return "Response to " + obj.toString();
}
public static native void defineBridgeMethod() /*-{
$wnd.testMe = function(msg) {
return #com.mycompany.mywebapp.client.MyWebApp::testMe(Ljava/lang/Object;);
};
}-*/;
Thanks!
You're not using msg, do you mean to call the function with it as a parameter:
public static native void defineBridgeMethod() /*-{
$wnd.testMe = $entry(function(msg) {
return #com.mycompany.mywebapp.client.MyWebApp::testMe(Ljava/lang/Object;)(msg);
});
}-*/;
or you can assign the function directly to window:
public static native void defineBridgeMethod() /*-{
$wnd.testMe = $entry(
#com.mycompany.mywebapp.client.MyWebApp::testMe(Ljava/lang/Object;)
);
}-*/;
The easiest way to export a gwt project to js is using gwt-exporter. Gwtexporter allows to export any gwt project without writing a single line of jsni code and it has plenty of features which allows to customize classes and methods exposed to js, and even it could produce the documentation for your js api.
In your case, implement the Exportable interface in the class with your static method, and annotate your method.
public class MyClass implements Exportable {
#Export("$wnd.testMe")
public static String testMe(Object obj) {
return "Response to " + obj.toString();
}
}
Then you have to call the exportAll() method in your entry point and leave the gwt compiler and gwtexporter generator do their magic
public void onModuleLoad() {
ExporterUtil.exportAll();
}
Here you have a tutorial of how to export a gwt-library to js, although the documentation of the project is quite good.
Some of the projects using this technique are chronoscope, gwtupload(jsupload) and gwtquery(jsquery).

Categories