Error while running the HTTP adapter in IBM Worklight - ibm-mobilefirst

I have created an HTTP adapter to call a procedure to add 2 numbers. Its a basic program to send input and display the output. Below is my code.
HTML:
First Integer: <input type="text" id="firstint"/>
Second Integer: <input type="text" id="secondint"/>
<input type="button" onclick="submitInput()" value="Submit"/>
DemoHTTPAdapter-impl.js :
function submitInput() {
var invocationData = {
adapter : 'DemoHTTPAdapter',
procedure : "getDemoAdd",
parameters : [$('#firstint').val(),$('#secondint').val()]
};
var options = {
onSuccess : success,
onFailure : failure
};
WL.Client.invokeProcedure(invocationData, options);
}
function getDemoAdd(firstint, lastint) {
return {
result : com.ibm.demo.DemoAdd.addTwoInteger(firstint,secondint)
}
}
The procedure is invoked through a java code as below in the DemoAdd.java:
package com.ibm.demo;
import java.util.logging.Logger;
public class DemoAdd {
private static final Logger logger = Logger.getLogger(DemoAdd.class.getName());
public static int addTwoInteger(int afirstInt, int aSecondInt) {
logger.info("Add Method Invoked with Parameter " + afirstInt + " & " + aSecondInt);
return (afirstInt + aSecondInt);
}
I am getting an error when I run the html.
submitInput() not defined.
whereas I have already defined the submitInput() method.

You've placed your submitInput function inside the adapter implementation file (DemoHTTPAdapter-impl.js) instead of in your common\js\main.js file.
You need to differentiate between the adapter scope, which resides on the Worklight Server and thus you cannot call it directly, to the application scope which resides in the application itself.
Because they are of different scopes, the parser tries to find submitInput, but cannot find it.
The application's JavaScript needs to call the Worklight framework in order to send the request to the server to invoke the adapter.
Move the following code to your main.js:
function submitInput() {
var invocationData = {
adapter : 'DemoHTTPAdapter',
procedure : "getDemoAdd",
parameters : [$('#firstint').val(),$('#secondint').val()]
};
var options = {
onSuccess : success,
onFailure : failure
};
WL.Client.invokeProcedure(invocationData, options);
}

Related

getting apache ignite continuous query to work without enabling p2p class loading

I have been trying to get my ignite continuous query code to work without setting the peer class loading to enabled. However I find that the code does not work.I tried debugging and realised that the call to cache.query(qry) errors out with the message "Failed to marshal custom event" error. When I enable the peer class loading , the code works as expected. Could someone provide guidance on how I can make this work without peer class loading?
Following is the code snippet that calls the continuous query.
public void subscribeEvent(IgniteCache<String,String> cache,String inKeyStr,ServerWebSocket websocket ){
System.out.println("in thread "+Thread.currentThread().getId()+"-->"+"subscribe event");
//ArrayList<String> inKeys = new ArrayList<String>(Arrays.asList(inKeyStr.split(",")));
ContinuousQuery<String, String> qry = new ContinuousQuery<>();
/****
* Continuous Query Impl
*/
inKeys = ","+inKeyStr+",";
qry.setInitialQuery(new ScanQuery<String, String>((k, v) -> inKeys.contains(","+k+",")));
qry.setTimeInterval(1000);
qry.setPageSize(1);
// Callback that is called locally when update notifications are received.
// Factory<CacheEntryEventFilter<String, String>> rmtFilterFactory = new com.ccx.ignite.cqfilter.FilterFactory().init(inKeyStr);
qry.setLocalListener(new CacheEntryUpdatedListener<String, String>() {
#Override public void onUpdated(Iterable<CacheEntryEvent<? extends String, ? extends String>> evts) {
for (CacheEntryEvent<? extends String, ? extends String> e : evts)
{
System.out.println("websocket locallsnr data in thread "+Thread.currentThread().getId()+"-->"+"key=" + e.getKey() + ", val=" + e.getValue());
try{
websocket.writeTextMessage("key=" + e.getKey() + ", val=" + e.getValue());
}
catch (Exception e1){
System.out.println("exception local listener "+e1.getMessage());
qry.setLocalListener(null) ; }
}
}
} );
qry.setRemoteFilterFactory( new com.ccx.ignite.cqfilter.FilterFactory().init(inKeys));
try{
cur = cache.query(qry);
for (Cache.Entry<String, String> e : cur)
{
System.out.println("websocket initialqry data in thread "+Thread.currentThread().getId()+"-->"+"key=" + e.getKey() + ", val=" + e.getValue());
websocket.writeTextMessage("key=" + e.getKey() + ", val=" + e.getValue());
}
}
catch (Exception e){
System.out.println("exception cache.query "+e.getMessage());
}
}
Following is the remote filter class that I have made into a self contained jar and pushed into the libs folder of ignite, so that this can be picked up by the server nodes
public class FilterFactory
{
public Factory<CacheEntryEventFilter<String, String>> init(String inKeyStr ){
System.out.println("factory init called jun22 ");
return new Factory <CacheEntryEventFilter<String, String>>() {
private static final long serialVersionUID = 5906783589263492617L;
#Override public CacheEntryEventFilter<String, String> create() {
return new CacheEntryEventFilter<String, String>() {
#Override public boolean evaluate(CacheEntryEvent<? extends String, ? extends String> e) {
//List inKeys = new ArrayList<String>(Arrays.asList(inKeyStr.split(",")));
System.out.println("inside remote filter factory ");
String inKeys = ","+inKeyStr+",";
return inKeys.contains(","+e.getKey()+",");
}
};
}
};
}
}
Overall logic that I'm trying to implement is to have a websocket client subscribe to an event by specifying a cache name and key(s) of interest.
The subscribe event code is called which creates a continuous query and registers a local listener callback for any update event on the key(s) of interest.
The remote filter is expected to filter the update event based on the key(s) passed to it as a string and the local listener is invoked if the filter event succeeds. The local listener writes the updated key value to the web socket reference passed to the subscribe event code.
The version of ignite Im using is 1.8.0. However the behaviour is the same in 2.0 as well.
Any help is greatly appreciated!
Here is the log snippet containing the relevant error
factory init called jun22
exception cache.query class org.apache.ignite.spi.IgniteSpiException: Failed to marshal custom event: StartRoutineDiscoveryMessage [startReqData=StartRequestData [prjPred=org.apache.ignite.configuration.CacheConfiguration$IgniteAllNodesPredicate#269707de, clsName=null, depInfo=null, hnd=CacheContinuousQueryHandlerV2 [rmtFilterFactory=com.ccx.ignite.cqfilter.FilterFactory$1#5dc301ed, rmtFilterFactoryDep=null, types=0], bufSize=1, interval=1000, autoUnsubscribe=true], keepBinary=false, routineId=b40ada9f-552d-41eb-90b5-3384526eb7b9]
From FilterFactory you are returning an instance of an anonymous class which in turn refers to the enclosing FilterFactory which is not serializable.
Just replace the returned anonymous CacheEntryEventFilter based class with a corresponding nested static class.
You need to explicitly deploy you CQ classes (remote filters specifically) on all nodes in topology. Just create a JAR file with them and put into libs folder prior to starting nodes.

can not read get property of undefined angular 2 error

hi I am trying to get city name from google api but getting that error below is my code
appcomponent class
import {Component, OnInit} from 'angular2/core';
import {marketComponent} from './market.component';
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {introComponent} from './intro.component';
import {geoService} from './service.geo';
import {JSONP_PROVIDERS} from 'angular2/http';
declare var google: any;
#Component({
selector: 'my-app',
templateUrl: 'app/app.component.html',
directives: [ROUTER_DIRECTIVES],
providers: [JSONP_PROVIDERS, geoService]
})
#RouteConfig([
{ path: '/intro', name: 'Intro', component: introComponent, useAsDefault: true },
{ path: '/market', name: 'Market', component: marketComponent },
])
export class AppComponent {
constructor(private _http: geoService) { }
public maps;
public cat_error: Boolean = false;
public xml_Latitude :string;
public xml_Lang: string;
ngOnInit() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(this.showPosition);
} else {
alert("Geolocation is not supported by this browser.");
}
var input: any = document.getElementById('google_places_ac');
var autocomplete = new google.maps.places.Autocomplete(input, {});
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var place = autocomplete.getPlace();
console.log(place)
});
}
showPosition(position) {
this.xml_Latitude = position.coords.latitude;
this.xml_Lang = position.coords.longitude;
this._http.getPlaces(this.xml_Latitude, this.xml_Lang).subscribe(
data => { this.maps = data },
err => { this.cat_error = true }
);
var result = this.maps.results;
var city = result[0].address_components[4].long_name + "," + result[0].address_components[6].long_name;
alert(city);
}
}
and geoservice file
import {Injectable} from 'angular2/core';
import { Response, Jsonp} from 'angular2/http';
import 'rxjs/add/operator/map';
#Injectable()
export class geoService {
constructor(private http: Jsonp) { }
public xml_Latitude: string;
public xml_Lang: string;
public getPlaces(xml_Latitude, xml_Lang) {
return this.http.get(`http://maps.googleapis.com/maps/api/geocode/json?latlng=
'${this.xml_Latitude}','${this.xml_Lang}'&sensor=true`)
.map((res: Response) => res.json())
.catch(this.handleError);
}
private handleError(error: Response) {
console.error(error);
return error.json().error || 'Server error';
}
}
error also says getplaces is not a function, I think I am missing something but don't know what....
In addition to the callback ordering problem identified by Thierry, you have a lost this context on this line:
navigator.geolocation.getCurrentPosition(this.showPosition);
The Problem
You have the classic JavaScript problem known as the incorrect this context.
The this keyword in JavaScript behaves differently than in does in other languages like C# and Java.
How this works
The this keyword, in a function, is determined as follows:
* If the function was created through a call to .bind, the this value is the argument provided to bind
* If the function was invoked through a method call, e.g. expr.func(args), then this is expr
* Otherwise
* If the code is in strict mode, this is undefined
* Otherwise, this is window (in a browser)
Let's look at how this works in practice:
class Foo {
value = 10;
doSomething() {
// Prints 'undefined', not '10'
console.log(this.value);
}
}
let f = new Foo();
window.setTimeout(f.doSomething, 100);
This code will print undefined (or, in strict mode, throw an exception).
This is because we ended up in the last branch of the decision tree above.
The doSomething function was invoked, the function wasn't a result of a bind call, and it wasn't invoked in a method syntax position.
We can't see the code for setTimeout to see what its invocation looks like, but we don't need to.
Something to realize is that all doSomething methods point to the same function object.
In other words:
let f1 = new Foo();
let f2 = new Foo();
// 'true'
console.log(f1.doSomething === f2.doSomething);
We know that setTimeout can only see the function we passed it, so when it invokes that function,
there's no way for it to know which this to provide.
The this context has been lost due to our referencing the method without invoking it.
The Red Flag
Once you know about this problems, they're easy to spot:
class Foo {
value = 10;
method1() {
doSomething(this.method2); // DANGER, method reference without invocation
}
method2() {
console.log(this.value);
}
}
The Solution
You have a few options here, each with its own trade-offs.
The best option depends on how often the method in question is invoked from differing call sites.
Arrow Function in Class Definition
Instead of using the normal method syntax, use an arrow function to initialize a per-instance member.
class DemonstrateScopingProblems {
private status = "blah";
public run = () => {
// OK
console.log(this.status);
}
}
let d = new DemonstrateScopingProblems();
window.setTimeout(d.run); // OK
Good/bad: This creates an additional closure per method per instance of your class. If this method is usually only used in regular method calls, this is overkill. However, if it's used a lot in callback positions, it's more efficient for the class instance to capture the this context instead of each call site creating a new closure upon invoke.
Good: Impossible for external callers to forget to handle this context
Good: Typesafe in TypeScript
Good: No extra work if the function has parameters
Bad: Derived classes can't call base class methods written this way using super.
Bad: The exact semantics of which methods are "pre-bound" and which aren't create an additional non-typesafe contract between your class and its consumers.
Function Expression at Reference Site
Shown here with some dummy parameters for explanatory reasons:
class DemonstrateScopingProblems {
private status = "blah";
public something() {
console.log(this.status);
}
public run(x: any, y: any) {
// OK
console.log(this.status + ': ' + x + ',' + y);
}
}
let d = new DemonstrateScopingProblems();
// With parameters
someCallback((n, m) => d.run(n, m));
// Without parameters
window.setTimeout(() => d.something(), 100);
Good/bad: Opposite memory/performance trade-off compared to the first method
Good: In TypeScript, this has 100% type safety
Good: Works in ECMAScript 3
Good: You only have to type the instance name once
Bad: You'll have to type the parameters twice
Bad: Doesn't easily work with variadic parameters
I think that you should move the result block into the subscribe callback associated the getPlaces method call:
showPosition(position) {
this.xml_Latitude = position.coords.latitude;
this.xml_Lang = position.coords.longitude;
this._http.getPlaces(this.xml_Latitude, this.xml_Lang).subscribe(
data => {
this.maps = data;
var result = this.maps.results; // <----------
var city = result[0].address_components[4].long_name + "," + result[0].address_components[6].long_name;
alert(city);
},
err => { this.cat_error = true }
);
}
It's because this.maps is undefined before the callback is called. And you try tyo get the result attribute before (this.maps.results).
Edit
I also see a problem at the line navigator.geolocation.getCurrentPosition. You could refactor your code this way:
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => { // <----
this.showPosition(position);
});
} else {
alert("Geolocation is not supported by this browser.");
}

Aurelia DataTables Recompile

I've been exploring Aurelia and so far have loved what I've seen. I've come accross an issue that I'm not really sure how to solve. I used jquery datatables for large results in my current app with angular, using server side fetches. Datatables has a function you can call whenever a new row is added to the table (fnRowCallback - http://legacy.datatables.net/ref#fnRowCallback, or "createdRow" - https://datatables.net/examples/advanced_init/row_callback.html#) - This is really handy as you can recompile the dom after each row (costly I know).
This enables you to reference functions that exist in the current scope (or viewModel) that the datatable exists in. For example:
In my view model:
export class DataTableTest{
test(){
alert('this is a test');
}
}
In the return results from a datatable fetch:
{name:'blah',age:40,actions:"<a click.delegate='test();'>Test</a>"}
For some reason I can't seem to figure out how to recompile an element once it has been added to the dom.
Does anyone have any ideas how you could do this?
UPDATE:
These are the original options I pass to datatables:
var options = {
"fnRowCallback": function (nRow) {
$compile($(nRow).contents())(scope);
}
};
I've tried the following after injecting that compiler service:
"fnRowCallback": function (nRow) {
this.compiler.compile($(nRow).contents()).fragment.innerHTML;
},
But I always get Uncaught TypeError: Cannot read property 'compile' of undefined - I do this in the "attached" function.. If I console.log(this.compiler) outside of these options, it's available. Also, we don't need to return html back to datatables, just run the compile on the contents. Many thanks for all your help!
You can use a compiler service to compile the element:
import {inject, ViewCompiler, ViewResources, Container} from 'aurelia-framework';
/**
* Compiler service
*
* compiles an HTML element with aurelia
*/
#inject(ViewCompiler, ViewResources, Container)
export class Compiler {
viewCompiler: any;
resources: any;
container: any;
constructor(viewCompiler, resources, container) {
this.viewCompiler = viewCompiler;
this.resources = resources;
this.container = container;
}
compile(templateOrFragment, ctx = null, viewSlot = null):any {
if (typeof templateOrFragment === "string") {
var temp = document.createElement('span');
temp.innerHTML = templateOrFragment;
templateOrFragment = temp;
}
var view = this.viewCompiler.compile(templateOrFragment, this.resources).create(this.container, ctx);
return view;
}
}
I use this in Kendo in the cell template callback function (it lets you return a string that will become the cell contents)
function(dataItem) {
var cellctx = { "$item": dataItem, "$parent": ctx };
return this.compiler.compile(templateString, cellctx).fragment.innerHTML;
}
(this happens in Aurelia's bind callback so the ctx is the executionContext)
I just wrap the current data item up in a context and alias it as $item so I can work with it.
Looks something like this:
<kendo-grid>
<kendo-grid-col title="Main Office" field="IsMainOffice">
<kendo-template><img if.bind="$item.IsMainOffice" src="/content/img/accept.png" /></kendo-template>
</kendo-grid-col>
</kendo-grid>

signalr avoid login repeat on load client side

I am using signalR pushnotification service.
I have created a partial view. Inside partial view. Here is my client side code:
<script type="text/javascript">
var objHub;
$(function () {
objHub = $.connection.AnilHub;
loadClientMethods(objHub);
$.connection.hub.start()
.done(function () { objHub.server.connect();
console.log('Now connected, connection ID=' + $.connection.hub.id); }
// at the same time i want to insert into database to set user is online.
objHub.server.login('user1');
)
.fail(function () { console.log('Could not Connect!'); });
function loadClientMethods(objHub) {
objHub.client.getMessages = function (message) {
$('#divMessage').append('<div><p>' + message + '</p></div>');
var height = $('#divMessage')[0].scrollHeight;
$('#divMessage').scrollTop(height);
}
}
</script>
Hub Code
[HubName("MyHub")]
public class MainHub : Hub
{
public void Connect()
{
try
{
string userGroup = "test";
var id = Context.ConnectionId;
Groups.Add(id, userGroup);
Clients.Caller.onConnected(id, userGroup);
}
catch
{
Clients.Caller.NoExistAdmin();
}
}
public void NotifyAllClients(string Message)
{
Clients.Group("test").getMessages(Message);
}
public override Task OnConnected()
{
// Set status online on database
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled = false)
{
// set status disconnct in database
return base.OnDisconnected(stopCalled);
}
}
}
Now I just want to avoid re-loading check of login. because everytime I refresh the page it will call the connect method and call the hub method. How to avoid the re-connect issue. How Do I persist the things, even hub is not handle sessions.
Please suggest...
inside your html, in first load, create a random id and store it in cookies.
In your hub code, create an arraylist and store these random ids with corresponding connection ID.
In your html, try to read the random id from the cookies during each page refresh, if it is not found, it's a new connection, if it is found, use the old random id with a new connection ID to connect to your hub. Then in your hub arraylist, for this particular random id, replace the old connection ID with the new connection ID.

Implementing an asynchronous call to a long running process MVC4

I have a large data set that holds up my UI so I thought I would create a background call to fill my local repository and display my other controls in the UI right away and load the results of the async call when I get a response.
I found a helpful tutorial but I am still having to wait until all my results are loaded before I see any controls.
http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4
CODE UPDATED
I have created a folder called Services and created FacilitiesService.cs in that folder, see below:
public class FacilitiesService
{
internal async Task<List<Facility>> GetFacilitiesBySourceDbAsync(string sourceDb)
{
var fac = new Facility();
var con = Connect(); // Omitted
try
{
con.Open();
}
catch (Exception ex)
{
Console.WriteLine("Error: GetFacilityBySourceDb " + ex.Message);
}
try
{
OracleDataReader reader = null;
// Requestor
var cmd = new OracleCommand("SELECT FACILITY, FACILITY_ID FROM MyTable where (source_db = '" + sourceDb + "')", con);
reader = cmd.ExecuteReader();
while (reader.Read())
{
fac.Add(new Facility()
{
FacilityName = reader["FACILITY"].ToString(),
FacilityId = reader["FACILITY_ID"].ToString()
});
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
con.Close();
con.Dispose();
}
return fac;
}
}
Then in my HomeController.cs I have the following:
public class HomeController
{
public async Task<List<Facility>> FacilitiesAsync()
{
ViewBag.SyncOrAsync = "Asynchronous";
var service = new FacilitiesService();
this._facilities = new List<Facility>();
var facilities = await service.GetFacilitiesBySourceDbAsync("TEST");
foreach (var item in facilities)
{
Facility fac = new Facility()
{
FacilityName = item.FacilityName,
FacilityId = item.FacilityId
};
_facilities.Add(fac);
}
return _facilities;
}
}
This is my Facility (model) class:
public class Facility : List<Facility>
{
[Required]
[Display(Name = "Facility")]
public string FacilityName { get; set; }
public string FacilityId { get; set; }
public Facility()
{
// Default Constructor
}
public Facility(string facilityName, string facilityId)
{
this.FacilityName = facilityName;
this.FacilityId = facilityId;
}
}
I am using an Ajax call to kick off the FacilitiesAsync method in the code behind from a function call in the About.cshtml page when the user tabs off the tetbox/input control with an id of "tags", I could switch this to something else later but I get the data back when I step through the code-behind and I see both the beforeSend and complete functions fire an alert:
<script type="text/javascript">
$(function () {
var availableTags = [
// Neeed data from function call to populate this list
];
$("#tags").autocomplete({
source: availableTags
});
$("#tags").focusout(function () {
var result = null;
$.ajax({
beforeSend: function() {
alert("Testing");
},
url: "FacilitiesAsync",
success: function(data) {
result = data;
},
complete: function () {
alert(result);
}
});
});
});
</script>
#using (Html.BeginForm()) {
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags" />
</div>
}
This works GREAT! However, I want to take the data from the call made to the code-behind to populate the array availableTags and I'm not sure how to do that. Suggestions?
There's a few things wrong with the implementations, and one problem with the approach.
First, the GetFacilitiesBySourceDbAsync does not contain an await. The compiler will issue a warning in this situation, informing you that it's not really an asynchronous method when you do that; it will run synchronously. That's an important warning. If you want asynchronous code, you'll need to make it asynchronous all the way. This means using the asynchronous database methods (ExecuteReaderAsync, etc).
Secondly, the Task.WhenAll call in Index is meaningless (since you only pass it a single task). Also, since Index is synchronous but calls an asynchronous method, the code not shown is probably calling Result, which is a no-no on ASP.NET. As I explain on my blog, this will actually deadlock once your async code is actually asynchronous.
But even if you fix these, it won't do what you want. There's a problem with the approach, and that is that async doesn't change the HTTP protocol (this is also a link to my blog). ASP.NET MVC understands asynchronous methods and will not complete the request until the async action method completes. You'll need to use something like AJAX to get the web page to do what you want.