Reputation: 1246
I am using IBM MobileFirst + Ionic + AngularJS, to create a program that search customer by name and list the result in a table.
Let's said I have a adapter :
<wl:adapter name="customerAdapter"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wl="http://www.ibm.com/mfp/integration"
xmlns:sql="http://www.ibm.com/mfp/integration/sql">
<displayName>customerAdapter</displayName>
<description>customerAdapter</description>
<connectivity>
<connectionPolicy xsi:type="sql:SQLConnectionPolicy">
<dataSourceDefinition>
<driverClass>oracle.jdbc.driver.OracleDriver</driverClass>
<url>jdbc:oracle:thin:@//10.128.2.155:1521/MyDB</url>
<user>admin</user>
<password>admin</password>
</dataSourceDefinition>
</connectionPolicy>
</connectivity>
<procedure name="searchCustomerByIC"/>
<procedure name="searchCustomerByNM"/>
<procedure name="searchCustomerByICandNM"/>
and this is the implementation : (For searchCustomerByNM)
var statementSearchCustomerByNM= WL.Server.createSQLStatement("select CUST_NM,CUST_NIRC,CUST_GENDER from TB_CUSTOMER where CUST_NM like UPPER(?) ");
function searchCustomerByNM(customerName) {
return WL.Server.invokeSQLStatement({
preparedStatement : statementSearchCustomerByNM,
parameters : [new String("%" + customerName + "%")]
});
}
The adapter work well.
Here is my GUI code:
<ion-view view-title="Customer">
<ion-content>
<div id = "pageCustomer">
<div class="list">
<label class="item item-input">
<input type="text" placeholder="Customer Name" ng model="customerName">
</label>
<label class="item item-input">
<input type="text" placeholder="Customer IC" ng-model="customerIc">
</label>
<button class="button button-full button-positive" ng-click="customerSearch(customerName)">
Search Customer
</button>
</div>
<hr>
<table id="myTable" cellpadding="5" align="center" >
<thead>
<tr>
<th data-priority="2">Name</th>
<th data-priority="1">NIRC</th>
<th data-priority="persist">Gender</th>
<td></td>
</tr>
</thead>
<tr ng-repeat="x in customers">
<td>{{ x.name }}</td>
<td>{{ x.ic}}</td>
<td>{{ x.gender }}</td>
</tr>
</table>
</div>
</ion-content>
</ion-view>
Here is my services:
app.service("customerSearchService",function()
{
this.searchByName = function(name){
var invokeData = {
adapter:"customerAdapter",
procedure:["searchCustomerByNM"],
parameters:[name]
};
var options = {
onSuccess:loadSQLQuerySuccess,
onFailure:loadSQLQueryFailure,
invocationContext:{'action':'Search Customer'}
};
WL.Client.invokeProcedure(invokeData,options);
function loadSQLQuerySuccess(result){
var customers = new Array();
var SJ = JSON.parse(JSON.stringify(result));
var length = SJ.invocationResult.resultSet.length;
for(var i=0;i<length;i++)
{
customers[i] = {name:SJ.invocationResult.resultSet[i].CUST_NM , ic:SJ.invocationResult.resultSet[i].CUST_NIRC , gender:SJ.invocationResult.resultSet[i].CUST_GENDER};
}
return customers;
}
function loadSQLQueryFailure(){
console.log("failureSend");
alert("failureSend");
var customers = new Array();
return customers;
}
}
});
This is my controller:
app.controller('CustomerCtrl', function($scope, customerSearchService,busyIndicator) {
$scope.getCustomers = function(customerName)
{
$scope.customers = [];
busyIndicator.show();
$scope.customers = customerSearchService.searchByName(customerName);
alert($scope.customers);
busyIndicator.hide();
};
$scope.customerSearch=function(customerName){
$scope.getCustomers(customerName);
}
})
How should I write a service and controller ? (provide code in my case please) I tried before, but my function keep return empty result, because the result is returned before the adapter fetch all data. How to wait the adapter get all data ?
Thanks in advance.
Upvotes: 1
Views: 1027
Reputation: 251
Might I also recommend that you read and follow Raymond Camden's blog. He's done several posts on MFP and Ionic, including adapter usage.
Upvotes: 1
Reputation: 7957
Can you try using $q ( https://docs.angularjs.org/api/ng/service/$q ) in your service
app.service("customerSearchService",function($q) // Add $q
{
this.searchByName = function(name){
var deferred = $q.defer();
var invokeData = {
adapter:"customerAdapter",
procedure:"searchCustomerByNM", // Note this is not an array
parameters:[name]
};
var options = {
onSuccess:loadSQLQuerySuccess,
onFailure:loadSQLQueryFailure,
invocationContext:{'action':'Search Customer'}
};
WL.Client.invokeProcedure(invokeData,options);
function loadSQLQuerySuccess(result){
var customers = new Array();
var SJ = JSON.parse(JSON.stringify(result));
var length = SJ.invocationResult.resultSet.length;
for(var i=0;i<length;i++)
{
customers[i] = {name:SJ.invocationResult.resultSet[i].CUST_NM , ic:SJ.invocationResult.resultSet[i].CUST_NIRC , gender:SJ.invocationResult.resultSet[i].CUST_GENDER};
}
//return customers;
deferred.resolve(customers);
}
function loadSQLQueryFailure(){
console.log("failureSend");
alert("failureSend");
var customers = new Array();
//return customers;
deferred.reject(customers);
}
return deferred.promise;
}
});
Upvotes: 1
Reputation: 49371
The main issue is that your searchByName
does not return anything.
Look closely, you'll see that the only return
statements are within other functions. So, your function call will end without returning anything. And like you said, it will return even before the invocation finished.
What you are experiencing is a typical flow of asynchronous
services.
I know of 2 approaches to this issue:
Read about Promises in general: http://www.html5rocks.com/en/tutorials/es6/promises/
Read about Promises in AngularJS: https://docs.angularjs.org/api/ng/service/$q
Read about Promises in Services: http://chariotsolutions.com/blog/post/angularjs-corner-using-promises-q-handle-asynchronous-calls/
Upvotes: 1