worklight adapter not calling from javascript - ibm-mobilefirst

Adpater is working, checked from calling Adapter option.
but invoking from Javascript no response is getting
pass is getting value say 123456,
but not getting response, no sucssess , no failure.
POST.xml
<displayName>POST</displayName>
<description>POST</description>
<connectivity>
<connectionPolicy xsi:type="http:HTTPConnectionPolicyType">
<protocol>http</protocol>
<domain>164.100.222.200</domain>
<port>80</port>
<connectionTimeoutInMilliseconds>60000</connectionTimeoutInMilliseconds>
<socketTimeoutInMilliseconds>60000</socketTimeoutInMilliseconds>
<maxConcurrentConnectionsPerNode>50</maxConcurrentConnectionsPerNode>
<!-- Following properties used by adapter's key manager for choosing specific certificate from key store
<sslCertificateAlias></sslCertificateAlias>
<sslCertificatePassword></sslCertificatePassword>
-->
</connectionPolicy>
</connectivity>
<procedure name="trackerLogin" />
<procedure name="setTrackerLocation" />
<procedure name="getTrackerLocation" />
<procedure name="updateStatus" />
</wl:adapter>
// POST-impl.js
function trackerLogin() {
var input = {
method : 'get',
returnedContentType : 'json',
path : '/WomenSafety/api/TrackerLogin/123456789012345?Password=123456'
};return WL.Server.invokeHttp(input);
}
// Main.js
function login(pass)
{
busyIndicator.show();
//var imei='123456789012345';
if(pass!=='')
{
var invocationData = {
adapter : "POST",
procedure : "trackerLogin",
parameters : []
};
WL.Client.invokeProcedure(invocationData,{
onSuccess : function(resp) {
alert('1111');
},
onFailure : function(resp) {
alert('2222');
},
});
/* var ONE_MINUTE = 60 * 1000;
var options = {
onSuccess : loginSuccess,
onFailure : loginFailure,
timeout : ONE_MINUTE
};
var invocationData = {
adapter : 'POST',
procedure : 'trackerLogin',
parameters : [imei,pass]
};*/
// WL.Client.invokeProcedure(invocationData, options);
alert('##-'+pass);
}
else
{
alert('Enter Password');
}
busyIndicator.hide();
}
function loginSuccess(result)
{
//var status=result.statusCode;
alert('1111');
if(status==200)
{
alert('Login');
}
else
{alert('Network Error');}
}
function loginFailure(result)
{alert('Server Error');}

Make sure that in the adapter XML you are point in the host property to an actual IP address of the server the adapter should connect to. i.e not localhost
Make sure the device and the MobileFirst Server are connected to the same network
Print the error you receive in the client once the adapter request fails, and act upon it: http://www.ibm.com/developerworks/websphere/techjournal/1212_paris/1212_paris.html
In the client-side, place alert()s before, inside, and after function to make sure you actually enter it (you can also debug your JavaScript in the Chrome DevTool with breakpoints...), and print the values of the objects you pass to see what is happening there.
You can also use Wireshark to inspect the network to see what is happening after the request was sent.
If you don't get anything, it sounds like a network problem.

Related

Can I set authorization headers with RequireJS?

We want to have 2 sets of resources for our AngularJS app (public/private) which uses RequireJS for dependency management. Basically everything on the login page would be public and once logged in, another angularjs app would be loaded (new requirejs config) that would load resources that require authentication to access.
Is there a way to configure requirejs to set an authorization header when loading resources?
It depends on what you mean by "resources" and how your server is configured. But in general - yes, since you are using AngularJS you can use the $httpProvider to inject an interceptor service.
For example, in a service:
var dependencies = ['$rootScope', 'userService'];
var service = function ($rootScope, userService) {
return {
request: function(config) {
var currentUser = userService.getCurrentUser();
var access_token = currentUser ? currentUser.access_token : null;
if(access_token) {
config.headers.authorization = access_token;
}
return config;
},
responseError: function (response) {
if(response.status === 401) {
$rootScope.$broadcast('unauthorized');
}
return response;
}
};
};
module.factory(name, dependencies.concat(service));
Then, after you configure your routes, you can use:
$httpProvider.interceptors.push( 'someService');
You can find some more information on interceptors here: https://docs.angularjs.org/api/ng/service/$http#interceptors
UPDATE
You might be able to use the text plugin to try and receive it, but I don't see the point in protecting client side code. Plus, if you want to use optimization the resources will just come in one file anyway...
config: {
text: {
onXhr: function (xhr, url) {
xhr.setRequestHeader('Authorization','Basic ' + token);
}
}
}
Refer to: custom-xhr-hooks
Another UPDATE
You could also use urlArgs (mainly used for cache invalidation) without using the text plugin:
require.config({
urlArgs: 'token='+token,
...
)}

How to pull data from SqlDataAdapter and store it in a JsonStore collection in MobileFirst

I have a SqlDataAdapter and I want to store it in a JsonStore collection in MobileFirst and Display it in table form. I have tried using Load() method but its not working.
this is my resultSetCollection.js file
;(function () {
WL.JSONStore.init({
resultSet : {
searchFields: {"EMP_NAME":"string","EMP_ID":"integer"}
}
}, {
// password : 'PleaseChangeThisPassword'
})
.then(function () {
return WL.Client.invokeProcedure({
adapter : 'EmployeeList',
procedure : 'getEmployeeLists',
parameters : []
});
})
.then(function (responseFromAdapter) {
alert('responseFromAdapter:' + JSON.stringify(responseFromAdapter.invocationResult.resultSet));
var accessor = WL.JSONStore.get('resultSet');
var data=responseFromAdapter.invocationResult.resultSet;
var changeOptions = {
replaceCriteria : ['EMP_ID', 'EMP_NAME'],
addNew : true,
markDirty : false
};
return accessor.change(data, changeOptions);
})
.then(function (response) {
console.log(response);
//Here I want to retrieve the collection and display it in a table
})
.fail(function (errObj) {
WL.Logger.ctx({pretty: true}).error(errObj);
});
}());
An adapter procedure request from a client application will have a response object in its success and failure callbacks. So lets assume that the request was successfull and data was returned from the backend server.
Lets also assume you have a JSONStore initialized and properly setup with a collection. You then only need to get the collection and add data to it.
The below example takes the full response from an HTTP adapter request and puts it as-is into a collection. You will of course need to create a better setup for your specific scenario...
Note that the code is not optimised and performance or with 100% proper logic. It's just a demonstration flow.
Tested in MobileFirst Platform Foundation 7.0.0.00.
main.js:
var collectionName = 'mydata';
var collections = {
mydata : {
searchFields : {data: 'string'},
}
};
function wlCommonInit(){
WL.JSONStore.init(collections).then(
function() {
var resourceRequest = new WLResourceRequest("/adapters/myadapter/getStories", WLResourceRequest.GET);
resourceRequest.send().then(resourceRequestSuccess, resourceRequestFailure);
}
);
}
function resourceRequestSuccess(response) {
WL.JSONStore.get(collectionName).add(response).then(
function(){
WL.Logger.info("successfully added response to collection");
displayDataFromCollection();
},
function() {
alert("failed adding response to collection");
}
);
}
function resourceRequestFailure() {
alert ("failure");
}
If you then like to fetch the data from the JSONStore and display it in the HTML, you could do something like this:
// get a specific item from the stored response and display it in a table
function displayDataFromCollection() {
WL.JSONStore.get(collectionName).findAll().then(
function(result) {
$("#mytable").append("<tr><td>" + result[0].json.responseJSON.rss.channel.title + "</td></tr>");
},
function() {
alert ("unable to display collection");
}
);
}
The index.html looks like this:
<table id="mytable">
</table>

Simple ember-cli-simple-auth and oauth2 project

I'm very new to 3rd party authentication and have not been able to make an API request to LinkedIn through the ember-cli-simple-auth addon paired with simple-auth-oauth2. My environment.js is below, where I've tried to piece together parts from Simple Labs' introduction1 and http://ember-simple-auth.com/ember-simple-auth-api-docs.html1, specifically at the bottom of where environment === 'test'. I don't get any errors after building the CLI project but I do get a notification in the browser's console (not warning or error) that says:
No authorizer was configured for Ember Simple Auth - specify one if backend requests need to be authorized.
Right now, I'm just trying to get an auth token back from LinkedIn and am not sure what the next step is. If I try to trigger the "authenticate" action on my login controller (extending the loginControllerMixin), I get an error in the console saying:
Uncaught Error: Assertion Failed: No authenticator for factory "authenticator:simple-auth-oauth2" could be found
What part or parts did I miss?
Environment.js:
// config/environment.js
/* jshint node: true */
module.exports = function(environment) {
var ENV = {
modulePrefix: 'seminars-me',
environment: environment,
baseURL: '/',
locationType: 'auto',
EmberENV: {
FEATURES: {
// Here you can enable experimental features on an ember canary build
// e.g. 'with-controller': true
}
},
APP: {
// Here you can pass flags/options to your application instance
// when it is created
}
};
if (environment === 'development') {
// ENV.APP.LOG_RESOLVER = true;
// ENV.APP.LOG_ACTIVE_GENERATION = true;
// ENV.APP.LOG_TRANSITIONS = true;
// ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
// ENV.APP.LOG_VIEW_LOOKUPS = true;
}
if (environment === 'test') {
// Testem prefers this...
ENV.baseURL = '/';
ENV.locationType = 'none';
// keep test console output quieter
ENV.APP.LOG_ACTIVE_GENERATION = false;
ENV.APP.LOG_VIEW_LOOKUPS = false;
ENV.APP.rootElement = '#ember-testing';
ENV['simple-auth-oauth2'] = {
serverTokenEndpoint: 'https://www.linkedin.com/uas/oauth2/authorization?response_type=code&client_id=757ll7ci1xd93u&scope=profile'
};
ENV['simple-auth'] = {
authorizer: 'simple-auth-authorizer:oauth2-bearer',
crossOriginWhitelist: ['https://www.linkedin.com'],
store: 'simple-auth-session-store:local-storage'
};
}
if (environment === 'production') {
}
return ENV;
};
The authenticator is actually registered as simple-auth-authenticator:oauth2-password-grant while you're using authenticator:simple-auth-oauth2.

Adapter response isn't displayed in a Dojo ListItem

I am using a Worklight adapter to get the RSS Feed from a web site; the adapter gets me the data in XML format, but the problem is I can't display the data in a Dojo LisItem.
These are the JS functions to call the Adapter:
function loadFeedsSuccess(result) {
console.log("Data sucesfully downloaded, HTTP " + result.status);
if(result.invocationResult.Items.length > 0) {
console.log("Server has returned " + result.invocationResult.Items.length + " item(s)"); displayRSSFeed(result.invocationResult.Items);
}
}
function loadFeedsFailure(result) {
console.log("Error while loading RSS feed: " + result.errorMessage);
}
function displayRSSFeed(rawData) {
var store = new dojo.store.Memory({data:rawData, idProperty: "guid"});
require(["dijit/registry"], function(registry){ var newsList = registry.byId("newsList"); dojo.empty("newsList");
store.query(function(news){
var newsItem = dojox.mobile.ListItem({label:news.title}); newsList.addChild(newsItem); });
});
}
function getNewsInit() {
var invocationData = {
adapter: "FeedReader",
procedure: "getStoriesFiltered"
};
var options = {
onSuccess: loadFeedsSuccess,
onFailure: loadFeedsFailure
};
WL.Client.invokeProcedure(invocationData, options);
}
The Browser doesn't diplay the data an shows the following Error:
[/NewsApp/apps/services/api/News/common/query] exception. ReferenceError: dojo is not defined worklight.js:4673
Uncaught ReferenceError: dojo is not defined
Any one have any idea how to fix my Problem?
if you're using Dojo and setting the async configuration property to true, then the dojo namespace is no longer available. This means that you can't use dojo.store.Memory or dojox.mobile.ListItem anymore.
To solve that issue you either have to disable the async function or use AMD to load your modules:
function displayRSSFeed(rawData) {
require([ "dijit/registry", "dojo/store/Memory", "dojox/mobile/ListItem", "dojo/dom-construct" ], function(registry, Memory, ListItem, domConstruct) {
var store = new Memory({data:rawData, idProperty: "guid"});
var newsList = registry.byId("newsList");
domConstruct.empty("newsList");
store.query(function(news){
var newsItem = new ListItem({label:news.title});
newsList.addChild(newsItem);
});
});
}
If it then throws the error:
ReferenceError: require is not defined
Then it means you're load loading the Dojo core at all, make sure you're loading dojo.js.

How to broadcast to other controllers when load with module.config or .run in Angularjs

I have a checking when reading the web page,then using the result to refresh sidebar by ng-repeat,but I have errors :
Uncaught Error: Unknown provider: $scope from myModule or
Uncaught Error: Unknown provider: $scope from sharedService
How can I resolve it?
Here is my code
module:
var myModule = angular.module('myModule', []);
service for broadcast:
myModule.factory('mySharedService', function($rootScope) { //service
var sharedService = {};
sharedService.keyHistory = [];
sharedService.linkHistory = [];
sharedService.prepForBroadcast = function(key,link) {
this.keyHistory = key;
this.linkHistory = link;
this.broadcastItem();
};
sharedService.prepForBroadcastAdd =function(key){
console.log(this.keyHistory.push(key));
//this.linkHistory = linkHistory+link;
this.broadcastItem();
};
sharedService.broadcastItem = function() {
$rootScope.$broadcast('handleBroadcast');
};
return sharedService;
});
config to do Checking:
myModule.config(function($scope,sharedService){
$.ajax({
url:"/fly/AJAX",
type:"POST",
contentType:'application/x-www-form-urlencoded; charset=UTF-8',
datatype:"json",
success:function(data){
if(data!=null){
var loginResult = $.parseJSON(data);
if (loginResult.success == true){
console.log("login success");
$("#userLable").html(loginResult.userName+'('+loginResult.loginID+')');//
if (loginResult.hasHistory==true) {
sharedService.prepForBroadcast(loginResult.searchHistory,[]);
console.log("broadcast");
}
};
}
}
});
});
SideCtrl:
function SideCtrl($scope,sharedService) {
$scope.$on('handleBroadcast', function() {
$scope.keyHistory =sharedService.keyHistory;
$scope.linkHistory = sharedService.linkHistory;
});
}
SideCtrl.$inject = ['$scope', 'mySharedService'];
THX !
The error is due to trying to request a $scope in a config block, which you can't do. If I understand what you're trying to do, then I also think you're over-complicating it. I'd solve the problem a little differently. The details would depend on your requirements and use case, but based on the information you gave...
I'd have a service responsible for communication with the server and storing the state:
app.factory( 'loginService', function ( $http ) {
var result;
function doRequest( data ) {
// just flesh out this post request to suit your needs...
return $http.post( '/fly/ajax', data, {} )
.then( function ( response ) {
// assuming you don't care about the headers, etc.
return response.data;
});
}
// Do it once initially
if ( ! angular.isDefined( result ) ) {
result = doRequest();
}
// return the service's public API
return {
getStatus: function () { return result; },
login: doRequest
};
});
Now the first time this service is requested, the $http request will be made. If you're accessing this from multiple controllers, the post will only occur once because of the isDefined statement. You can then use this in your controllers:
app.controller( 'MainCtrl', function( $scope, loginService ) {
loginService.getStatus().then( function ( data ) {
// do whatever you need to with your data.
// it is only guaranteed to exist as of now, because $http returns a promise
});
});
Every controller accesses it the same way, but it was still only called once! You can set values against the scope and access it from your views, if you want:
app.controller( 'MainCtrl', function( $scope, loginService ) {
loginService.getStatus().then( function ( data ) {
$scope.loginId = data.loginID;
});
});
And in your view:
<h1>Welcome, {{loginId || 'guest'}}!</h1>
And if you need to, you call the function again:
app.controller( 'MainCtrl', function( $scope, loginService ) {
// ...
loginService.login( $scope.user ).then( function ( data ) {
$scope.loginId = data.loginID;
});
// ...
});
As you can see, broadcasting an event is totally unnecessary.
I would do it differently. I would create some sort of more top-level controller, like function MainController($rootScope, $scope, sharedService) and wire it up with body: <body ng-controller='mainController' ng-init='init()'. After that you should create init() method in MainController.
Inside this initialization method I would call sharedService which should make AJAX request (via $http! that's the best practice, and it's very similar to jQuery) and broadcast proper event when required.
That way you make sure to call initialization just once (when MainController is initializing), you stick to the angular's best practices and avoid dodgy looking code.