I am facing an issue while integrating signalr with angular, i can able to call a hub function from angular factory, but i can't push method from server to client.
app.factory("Signalr", function ($rootScope, $q) {
var MyHub = $.connection.MyHub;
$.connection.hub.url = "mydomain.com/signalr";
var SignalR = {};
SignalR.StratHub = function () {
connection = $.connection.hub.start();
},
SignalR.CreateConnection = function (UniqueId) {
var defer = $q.defer();
connection.done(function () {
MyHub.server.connectNetPetDevice(UniqueId).done(function
(ConnectionInfo) {
if (ConnectionInfo) {
defer.resolve(ConnectionInfo);
}
else {
defer.reject('Failed');
}
})
})
return defer.promise;
},
SignalR.TestCall = function () {
MyHub.client.testCall("Test") = function (data) {
alert(data);
};
}
return SignalR;
});
In Controller
app.controller("Controller", function ($scope, Signalr) {
Signalr.StratHub();
Signalr.CreateConnection("123456789321456").then(function (ConnectionInfo) {
alert(ConnectionInfo);
})
SignalR.TestCall().then(function (data) {
alert(data)
});
})
Related
I am pretty new to web technologies, I got bits & pieces of code from internet and somehow managed to form this code.
I have to get data to a web app developed in angularjs from websocket through APIs.
here is the code,
angular.module("MyApp")
.service("myService", function ($rootScope, $q) {
return {
_prevTransmittingStatus: null,
transmitting: false,
_transmissionStatus: function () {},
socket: null,
socket_msg_id: 0,
socket_history: {},
url: "ws://localhost:4848/app/",
setOnTransmissionStatus: function (callback) {
var self = this;
this._transmissionStatus = function () {
if (self.transmitting != self._prevTransmittingStatus) {
self._prevTransmittingStatus = self.transmitting
callback(self.transmitting)
} else {}
}
},
connect: function (callback) {
var deferred = $q.defer();
var promise = deferred.promise;
var self = this
this.transmitting = true;
this._transmissionStatus();
this.socket = new WebSocket(this.url);
this.socket.addEventListener('open', function (e) {
self.transmitting = false;
self._transmissionStatus();
deferred.resolve("connected")
});
this.socket.addEventListener('message', function (e) {
var asJson = angular.fromJson(e.data)
var replyId = asJson.id;
var histItem = self.socket_history[replyId]
self.transmitting = false;
self._transmissionStatus();
if (angular.isUndefined(asJson.error)) {
$rootScope.$apply(histItem.defer.resolve(asJson.result))
} else {
**GetActiveDoc();/*how to call this */**
console.log("---rejected-----");
$rootScope.$apply(histItem.defer.reject(asJson.error))
}
});
return promise;
},
disconnect: function () {
this.socket.close();
this.transmitting = false;
this._transmissionStatus();
return this;
},
send: function (msg, scope, callback, onerror) {
console.info("SEND:", msg)
var _this = this;
this.transmitting = true;
this._transmissionStatus();
if (!this.socket) {
return this.connect().then(
function (histItem) {
console.log("CONNECT SUCCESS", histItem)
},
function (histItem) {
console.log("CONNECT ERROR", histItem)
}
).then(function () {
return _this.send(msg, scope);
})
} else if (this.socket) {
console.log("socket is open")
var deferred = $q.defer();
var promise = deferred.promise;
msg.id = this.socket_msg_id;
this.socket_history[msg.id] = {
id: msg.id,
defer: deferred,
scope: scope,
msg: msg
};
this.socket_msg_id++
this.socket.send(angular.toJson(msg))
return promise
}
},
isConnected: function () {
return this.socket ? true : false;
}
}
});
I am getting an error "Uncaught TypeError: Cannot read property 'defer' of undefined at Websocket" only for the first time when I open my web app.
Can some one explain how to resolve this.
solved it myself, just added/modified the code as follows,
if(replyId >= 0){
$rootScope.$apply(histItem.defer.resolve(asJson.result))
}
can someone help me with this code? I have problem with return value, function in controller return only
var products = {"id": 3};
I want to collect value from http.get, can someone tell me how to do that??
Controller:
$scope.product = {};
$scope.init = function () {
$scope.loadProducts()
}
$scope.loadProducts = function () {
// $http.get("/products/list").then(function (resp) {
// $scope.products = resp.data;
// })
$scope.products = getListProducts.loadProducts();
}
Service
var myServices = angular.module('myServices', []);
myServices.service('getListProducts', ['$http', function ($http) {
var products = {"id": 3};
this.loadProducts = function () {
$http.get("/products/list").then(function (resp) {
products = resp.data;
})
return products;
}
}]);
you are returning products before http success , instead use promises and resolve when http success
$scope.product = {};
$scope.init = function () {
$scope.loadProducts()
}
$scope.loadProducts = function () {
// $http.get("/products/list").then(function (resp) {
// $scope.products = resp.data;
// })
$scope.productPromise = getListProducts.loadProducts();
productPromise..then(function (resp) {
$scope.products = resp.data;
});
}
Service
var myServices = angular.module('myServices', []);
myServices.service('getListProducts', ['$http', function ($http) {
var products = {"id": 3};
this.loadProducts = function () {
return $http.get("/products/list");
}
}]);
Make use of promises to enforce serialization of your async code.
Refactor your service method as:
this.loadProducts = function () {
var getProducts = new Promise(function(resolve,reject){
$http.get("/products/list").then(function (resp) {
resolve(resp.data);
})
});
return getProducts;
};
And your Controller method as:
getListProducts.loadProducts().then(function(data){
//success callback
$scope.products = data;
});
You can provide the error callbacks as well.
Hope this helps !
You should use promises to return values from your service.
You can use $q in your service. It would help functions to run asynchronously.
myServices.service('getListProducts', ['$http','$q', function ($http,$q) {
var products = {"id": 3};
this.loadProducts = function () {
var deferred = $q.defer();
$http.get("/products/list").then(function (resp) {
products = resp.data;
deferred.resolve(products);
},function(error){
deferred.reject(error);
});
return deferred.promise;
}
}]);
And Your method in controller should handle success and error callbacks :
$scope.loadProducts = function () {
getListProducts.loadProducts().then(function(response){
$scope.products=response;
},function(error){
//your processing logic
});
}
I hope this would help you.
Given the following test.
How do I ensure that the promise is resolved, and the data is provided.
describe("component: FicaStatusComponent",
function () {
var fs;
beforeEach(function () {
module("aureus",
function ($provide) {
$provide.service("ficaService", function () {
this.status = function () {
return $q(function (resolve, reject) {
resolve([{ documentType: { id: 1 } }]);
});
}
})
});
});
beforeEach(inject(function (_$componentController_, _ficaService_) {
$componentController = _$componentController_;
fs = _ficaService_;
}));
it("should expose a `fica` object", function () {
console.log('should expose');
var bindings = {};
var ctrl = $componentController("ficaStatus", null, bindings);
expect(ctrl.fica).toBeDefined();
});
it("compliant with no documents should not be compliant",
function () {
var ctrl = $componentController("ficaStatus");
expect(ctrl.fica.length).toEqual(1);
});
}
);
The second test compliant with no documents... is failing. The length is zero. The other test is passing, so I have the correct controller being instantiated, the property is defined.
The mock service is not resolving the data correctly, probably because the Promise is still executing, or not being called at all.
Here is the implementation of the controller for the component:
var FicaStatusController = (function () {
function FicaStatusController($log, $loc, ficaService) {
var _this = this;
this.$log = $log;
this.$loc = $loc;
this.ficaService = ficaService;
this.fica = [];
this.ficaService.status(1234).then(function (_) { return _this.fica = _; });
}
The service is as follows:
var FicaStatusService = (function () {
function FicaStatusService($log, $http) {
this.$log = $log;
this.$http = $http;
}
FicaStatusService.prototype.status = function (accountNumber) {
var url = "api/fica/status/" + accountNumber;
this.$log.log("status: " + url);
return this.$http
.get(url)
.then(function (_) { return _.data; });
};
return FicaStatusService;
}());
...
First, u can use $q like:
this.status = function () {
return $q.when([{ documentType: { id: 1 } }]);
}
Second, to resolve promise use $scope.$digest, $rootScope.$digest:
var a = $q.when({test: 1});
expect(a.test === 1).toBe(false);
$rootScope.$digest();
expect(a.test === 1).toBe(true);
I am creating a service called ActiveUserProfileService, but when I call its function in a controller I get undefined as a result and I cannot figure out why. The strangest part is that, in the ActiveUserProfileService service, the information from the UserService is displayed through console.log, so I'm receiving the information, but after calling the ActiveUserProfileService in the controller, it gives me undifened. It seems like the data isn't passed around. Can someone help me ?
UserService.js:
(function () {
'use strict';
angular
.module('myApp')
.factory('UserService', UserService);
UserService.$inject = ['$http'];
/* #ngInject */
function UserService($http) {
var service = {
getAuthenticatedUser: getAuthenticatedUser,
getUserInformation: getUserInformation
};
return service;
function getUserInformation(idUser) {
return $http.post('api/user/details', {idUser: idUser});
}
function getAuthenticatedUser() {
return $http.get('api/user');
}
}
})();
ActiveUserProfileService.js
(function () {
'use strict';
angular
.module('myApp')
.factory('ActiveUserProfileService', ActiveUserProfileService);
ActiveUserProfileService.$inject = ['$http','UserService'];
/* #ngInject */
function ActiveUserProfileService($http, UserService) {
var service = {
isAccount: isAccount
};
return service;
////////////////
function isAccount(accountName) {
UserService.getAuthenticatedUser()
.then(function (response) {
var data = response.data;
UserService.getUserInformation(data.user.id)
.then(function (response) {
var userDetails = response.data;
console.log("It is");
console.log(accountName == userDetails.account_types[0].description_internal);
return accountName == userDetails.account_types[0].description_internal;
});
})
}
}
})();
My controller:
(function () {
'use strict';
angular
.module('myApp')
.controller('WizardController', WizardController);
WizardController.$inject = [
'UserService',
'ActiveUserProfileService'
];
/* #ngInject */
function WizardController(UserService,ActiveUserProfileService) {
var vm = this;
console.log("ActiveUserProfileService");
console.log(ActiveUserProfileService.isAccount("professional")); //is Returning me undefined
}
})
();
The point is, you're trying to return a value for isAccount inside another function, a callback. When you do that, you're returning a value to this function, and not isAccount itself, so isAccount will not return anything, undefined, then.
As you are calling an assynchronous method, then isAccount must be assynchronous as well,
Replace
function isAccount(accountName) {
UserService.getAuthenticatedUser()
.then(function (response) {
var data = response.data;
UserService.getUserInformation(data.user.id)
.then(function (response) {
var userDetails = response.data;
console.log("It is");
console.log(accountName == userDetails.account_types[0].description_internal);
return accountName == userDetails.account_types[0].description_internal;
});
})
}
with
function isAccount(accountName) {
var deferred = $q.defer();
UserService.getAuthenticatedUser()
.then(function (response) {
var data = response.data;
//when the user is loaded, then you resolve the promise you has already returned
UserService.getUserInformation(data.user.id)
.then(function (response) {
var userDetails = response.data;
console.log("It is");
console.log(accountName == userDetails.account_types[0].description_internal);
deferred.resolve(accountName == userDetails.account_types[0].description_internal);
return; //here is not isAccount return, but anonymous inner function 'function (response)', you got it?
});
});
return deferred.promise; //return as soon as creates the promise
}
For sure you'd have to inject $q service as well
I have this:
app.factory('contacts', function ($rootScope, $q, cordovaReady) {
return {
find: cordovaReady(function (filter) {
var deferred = $q.defer();
var options = new ContactFindOptions();
options.filter = filter;
options.multiple = true;
var fields = ["displayName", "name", "addresses", "emails"];
navigator.contacts.find(fields, function (contacts) {
$rootScope.$apply(function () {
deferred.resolve(contacts);
});
}, function (error) {
$rootScope.$apply(function () {
deferred.reject(error);
});
}, options);
return deferred.promise;
})
};
and
app.factory('cordovaReady', function () {
return function (fn) {
var queue = [];
var impl = function () {
queue.push(Array.prototype.slice.call(arguments));
};
document.addEventListener('deviceready', function () {
queue.forEach(function (args) {
fn.apply(this, args);
});
impl = fn;
}, false);
return function () {
return impl.apply(this, arguments);
};
};
});
Whenever I call from the controller:
var contactSearch = '';
contacts.find(contactSearch).then(function (contacts) {
$scope.contacts = contacts;
}, function (error) {
console.log(error);
});
I get:
ReferenceError: ContactFindOptions is not defined
at Object.<anonymous>
I made sure to wrap the function with cordovaReady. Why is this happening?
Can you go through this answer -
Uncaught ReferenceError: ContactFindOptions is not defined
Also make sure that your app.js should be included after cordova.js or phonegap JS in index.html.
I also suggest use ng-cordova wrapper for contact plugin.
include ng-cordova.js before your js in index file.
Inject ngCordova to your app module.
Inject $cordovaContacts to your service/factory.
For more visit http://ngcordova.com/
Ex.
var services = angular.module("services", ['ngCordova']);
services.service('contact', contact);
function contact($cordovaContacts, $q) {
return {
find : function() {
var deferred = $q.defer();
var options = {};
options.filter = "";
options.multiple = true;
$cordovaContacts.find(options).then(function(contacts) {
for (var i = 0; i < contacts.length; i++) {
if (null != contacts[i].phoneNumbers) {
for (var j = 0; j < contacts[i].phoneNumbers.length; j++) {
alert(contacts[i].phoneNumbers[j].value);
if (null != contacts[i].emails) {
alert(contacts[i].emails[0].value);
}
alert(contacts[i].displayName);
}
}
deferred.resolve();
}, function(err) {
deferred.reject();
alert("error in contact find");
});
return deferred.promise;
};
};
Hope this answer help you.