Sharing data stored in angularjs - asp.net

I'm trying to shared data between controller.
I'm calling data, then stored in AngularJS Factory variable.
My goal when stored the data was to make it accessible to any controller. But in application, every time i called the stored data from each controller, seems like i got a new instance of my factory instead of my factory that already contain the data.
Do you think i'm doing the wrong way when using factory or there was something i've been missed ?
Here it is
Factory Code:
var Credentials = ['abc'];
function load() {
var service = HeaderService.get("api/CredentialsAPI/get");
service.then(function (response) {
if (response.status == 200)
Credentials = response.data;
});
alert("inside:" + Credentials.length);
}
load();
return {
SubmitCredentials : function (obj) {
angular.forEach(obj, function (value) {
Credentials.push(value);
});
},
GetCredentials : function (name) {
var datax = {};
alert(Credentials.length)
angular.forEach(Credentials, function (value) {
if (value.Name == name) {
datax = value;
}
});
return datax;
}
}
Home Controller:
loadHome();
function loadHome() {
$scope.Credentials = CredentialsService.GetCredentials("Task");
}
AssignTask
$scope.showSubmitView = false;
//----------------------------------function--------------------------------------
$scope.Credentials[] = CredentialsService.GetCredentials("Task");

You're referencing a new array every time. That's why you're getting new data. You should be referencing the service instead, and have the service take care of the push() and get for you.
Factories and Services are singletons... Meaning they're only instantiated once. The pattern to share data is below:
Factory
app.factory('CredentialService',["$http", function($http) {
var credentials = [];
var submitCredentials = function(obj) {
angular.forEach(obj, function(value) {
credentials.push(value);
});
}
var getCredentials = function(name) {
var datax = {};
if(credentials.length === 0)
return datax;
angular.forEach(credentials, function(value) {
if(value.Name === name) {
datax = value;
break; //i think you meant to break; over here
}
});
return datax;
}
//return the service;
return {
getCredentials: getCredentials,
submitCredentials: submitCredentials
};
}]);
Controller
app.controller("Ctrl1", ["$scope", "CredentialService", function($scope, CredentialService) {
var credObj = CredentialService.getCredentials('blahblahblah');
var someNewCredObj = 'blahhhh';
CredentialService.submitCredentials(someNewCredObj);
}]);

Related

Angular client with signalR service not fire controller method

I have angular service where i got methods which are called from server when user connect or disconnect from my app
(function () {
//'use strict';
app.service('PrivateChatService', ['$rootScope', '$location', function PrivateChatService($rootScope, $location){
var online_users = [];
var proxy = $.connection.chatHub;
return {
addOnlineUser:
proxy.client.newOnlineUser = function (user) {
var newUser = ({
connectionId: user.ConnectionId,
UserName: user.UserName
});
online_users.push(newUser);
$.connection.hub.start()
},
removeOfflineUser: proxy.client.onUserDisconnected = function (id, user) {
var index = 0;
//find out index of user
angular.forEach(online_users, function (value, key) {
if (value.connectionId == id) {
index = key;
}
})
online_users.splice(index, 1);
$.connection.hub.start()
},
}
}])})();
Here i got controller method which i want to be fired when server calls newOnlineUser
PrivateChatService.newOnlineUser(function (user) {
$scope.online_users.push(newUser);
console.log("newOnlineUser finished");
});
So my question is. Is it possible to make with generated proxy or i have to use non-generated proxy access to those methods with which i am not very familiar.
With generated proxy as i show above it never reach my controller method to update my data in controller scope
Since nobody responded, what i find somehow odd. I found out this is working. I am not sure if this is good aproach since nobody answered and i didnt find any information how should this be solved.
app.service('PrivateChatService', ['$rootScope', '$location', function PrivateChatService($rootScope, $location){
var online_users = [];
var connection = $.hubConnection();
var proxy = connection.createHubProxy('chatHub');
function signalrCall(eventName, callback) {
proxy.on(eventName, function (user) {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(proxy, args)
})
});
connection.start();
}
return {
addOnlineUser: function (eventName, callback) {
signalrCall(eventName, callback);
},
getActiveUsers: function (eventName, callback) {
signalrCall(eventName, callback);
},
removeOfflineUser: function (eventName, callback) {
signalrCall(eventName, callback);
}
}
}])
angular controller methods
PrivateChatService.addOnlineUser("newOnlineUser", function (user) {
var newUser = ({
connectionId: user.ConnectionId,
UserName: user.UserName
});
$scope.online_users.push(newUser);
console.log("newOnlineUser finished");
});
PrivateChatService.getActiveUsers("getOnlineUsers", function (onlineUsers) {
angular.forEach($scope.online_users, function (scopeValue, scopeKey) {
//loop through received list of online users from server
angular.forEach(onlineUsers, function (serverListValue, serverListKey) {
if (!(serverListValue.ConnectionId == scopeValue.connectionId)) {
var newUser = ({
connectionId: serverListValue.ConnectionId,
UserName: serverListValue.UserName
});
$scope.online_users.push(newUser);
}
})
})
console.log("getOnlineUsers finished");
});
PrivateChatService.removeOfflineUser("onUserDisconnected", function (user) {
var index = 0;
//find out index of user
angular.forEach($scope.online_users, function (value, key) {
if (value.connectionId == user) {
index = key;
}
})
$scope.online_users.splice(index, 1);
});

How to return "then()" method in angularjs?

My case:
app.js:
let app = angular.module('myApp', []);
app.controller('login', function ($scope, $login) {
$scope.account = {};
$scope.loginForm_submit = function ($event, account) {
$event.preventDefault();
if ($login.isValid(account)) {
$login.submit(account);
// goal:
$login.submit(account).then(function () {
window.location = '/'
}, function (msg) {
console.log(msg)
});
}
};
});
login.js:
app.factory('$login', function () {
let o = {
isValid: function (x) {
let success = false;
// validating...
return success
},
submit: function (x) {
// prevent to force submitting
if (this.isValid(x)) {
let formData = new FormData(), xhttp = new XMLHttpRequest();
// appending data to 'formData' via 'x'...
xhttp.onreadystatechange = function () {
if (xhttp.readyState === XMLHttpRequest.DONE) {
let data = JSON.parse(xhttp.responseText);
if (data['Success']) {
// return then() with successCallback() function
} else {
let msg = data['ErrorMessage'];
// return then() with errorCallback() function
}
}
}
xhttp.open('POST', '/account/register');
xhttp.send(formData);
}
}
}
return o
});
data is an object like:
let data = {
'Success': false,
'ErrorMessage': 'Invalid login attempt.'
};
I want to return then() method after submitting to access result. How can I do that?
UPDATE:
In controller:
[HttpPost]
public async Task<ObjectResult> Login(LoginViewModel model)
{
IDictionary<string, object> value = new Dictionary<string, object>();
value["Success"] = false;
if (ModelState.IsValid)
{
// login
value["Success"] = true;
}
return new ObjectResult(value);
}
First of all, you should avoid using $ for your own functions.
About your problem, you need to use $q. And you should use what angular offers to you.
Let me give you this :
app.factory('loginFactory', function($q, $http) {
var ret = {
isValid: isValid,
submit: submit
}
return ret;
function isValid(x) {
// Your code ...
return false;
}
function submit(x) {
// x is your form data, assuming it's a JSON object
var deferred = $q.defer();
// Assuming you're posting something
$http.post('yoururl', x,{yourConfigAsAnObject: ''})
.then(function(success){
console.log(success.data);
deferred.resolve(success.data);
}, function(error) {
console.log(error);
deferred.reject(error);
});
return deferred.promise;
}
});
Now, in your controller, you can use
loginFactory.submit(yourParam).then(function(success){
// Your code
}, function(error) {
// Your code
});
app.factory('$login', function ($q) {
let o = {
isValid: function (x) {
let success = false;
// validating...
return success
},
submit: function (x) {
var d = $q.defer();
// prevent to force submitting
if (this.isValid(x)) {
let formData = new FormData(), xhttp = new XMLHttpRequest();
// appending data to 'formData' via 'x'...
xhttp.onreadystatechange = function () {
if (xhttp.readyState === XMLHttpRequest.DONE) {
let data = JSON.parse(xhttp.responseText);
if (data['Success']) {
// return then() with successCallback() function
d.resolve('success');
} else {
let msg = data['ErrorMessage'];
d.reject(msg);
// return then() with errorCallback() function
}
}
}
xhttp.open('POST', '/account/register');
xhttp.send(formData);
}
else {
d.reject('error');
}
return d.promise;
}
}
return o
});
dude,I made a sample function with promise
$q should be injected as dependency
class AppUserService {
constructor($http,CONFIG_CONSTANTS,$q, AuthService) {
this.API_URL = CONFIG_CONSTANTS.API_URL;
this.$http = $http;
this.$q = $q;
this.api_token = AuthService.api_token;
}
getAppUserList() {
const deferred = this.$q.defer();
this.$http.get(`${this.API_URL}/customer?api_token=${this.api_token}`)
.success(response => deferred.resolve(response))
.error(error => deferred.reject(error));
return deferred.promise;
}
}
its in ES6 form.
How to use:
AppUserService.getAppuserList().then(success => {
// code for success
},error => {
// code for error
})
submit: function (x) {
return $q(function (resolve, reject) {
// prevent to force submitting
if (this.isValid(x)) {
let formData = new FormData(), xhttp = new XMLHttpRequest();
// appending data to 'formData' via 'x'...
xhttp.onreadystatechange = function () {
if (xhttp.readyState === XMLHttpRequest.DONE) {
let data = JSON.parse(xhttp.responseText);
if (data['Success']) {
resolve(data);
// return then() with successCallback() function
} else {
let msg = data['ErrorMessage'];
reject(msg);
}
}
}
xhttp.open('POST', '/account/register');
xhttp.send(formData);
}
else
reject('x not valid');
}
}
}
But I recommended to use angular $http service.

Meteor. Problems with subscribe/publish

i have a problem.
I'm trying to build highcharts graphic.
How it works:
I'm going to my route ('ship.details'), and here i have not problems.
My problem:
subsription to (ships_snapshots_all) not working.
My publish.js:
Meteor.publish("ships_snapshots", function(user, options) {
if(!this.userId) return null;
if(this.userId) {
console.log('subsribed by ' + user);
return ships_snapshots.find({userId: user}, options);
}
});
Meteor.publish("ships_snapshots_all", function() {
return ships_snapshots.find({});
})
My subscribe.js (in lib folder):
Meteor.subscribe('ships_snapshots');
Meteor.subscribe('ships_snapshots_all');
Problem 100% in my subsription, because if i'm installing autopublish all working good. And problem in my router i think.
router.js:
Router.route('/ships/details', {
name: 'ship.details',
loadingTemplate: 'loading',
onBeforeAction: function() {
var shipId = Session.get('currentShipId');
if(!shipId) {
Router.go('user.ships');
} else {
this.next();
}
},
waitOn: function() {
if (Meteor.isClient) {
var getCompare = Meteor.user().profile.wows.compareWith;
console.log(getCompare);
var user2 = Meteor.users.findOne({"profile.wows.nickname": getCompare});
var user2Id = user2._id;
if (getCompare) {
var user2 = Meteor.users.findOne({"profile.wows.nickname": getCompare});
if (user2) {
var user2Id = user2._id;
}
}
if (getCompare) {
var handle = Meteor.subscribe('ships_snapshots', Meteor.user()._id) && Meteor.subscribe('ships_snapshots', user2Id) && Meteor.subscribe('userSearchInfo', getCompare);
Session.set('compareWith', user2);
console.log('user2 _____');
console.log(user2);
return handle
} else {
var handle = Meteor.subscribe('ships_snapshots', Meteor.user()._id) && Meteor.subscribe('ships_snapshots', user2Id);
return handle
}
}, data: function() {
if (handle.ready()) {
var shipname = this.params.shipName;
var obj = {};
var query = ships.findOne();
var shipId = Session.get('currentShipId');
var result;
_.each(Meteor.user().profile.wows.ships, function(row) {
if (row.ship_id === shipId) {
result = row;
}
});
return result;
}
}
});
I think my problem in subscripion for ship_snapshots. Something going wrong here, but i can't to resolve this problem.
What exactly do you mean by "not working"? From your code I would assume that you're always seeing all the ship snapshots.
You shouldn't have the subscribes in /lib if you have them in your router. If you have Meteor.subscribe('ships_snapshots_all'); in /lib then you should always be seeing all the ship snapshots (assuming you're not stopping that subscription anywhere).
Also your subscription to all should be:
Meteor.publish("ships_snapshots", function(user, options) {
if(this.userId) {
console.log('subsribed by ' + user);
return ships_snapshots.find({userId: user}, options);
} else this.ready();
});
You don't want to return null when there is no user, you can just mark the subscription as ready without finding any records. This is not the cause of your problem but just good practice.
Meteor.publish("ships_snapshots", function(user, options) {
if(!this.userId) return null;
if(this.userId) {
console.log('subsribed by ' + user);
return ships_snapshots.find({userId: user._id}, options);
}
});
In your publish script, is user really an id or is it a user object? I changed it to user._id. Please check that.

Can't load dictionary using knockout mapping plugin

I found the solution how to use the observable array as dictionary on http://jsfiddle.net/karlhorky/D4D3f/
ko.observableArray.fn.indexBy = function (keyName) {
var index = ko.computed(function () {
var list = this() || [];
var keys = {};
ko.utils.arrayForEach(list, function (v) {
if (keyName) {
keys[v[keyName]] = v;
} else {
keys[v] = v;
}
});
return keys;
}, this);
this.findByKey = function(key) {
return index()[key];
};
return this;
};
I'd like to load data to dictionary using mapping plugin
this.Load = function () {
//this.items.
var mapping = {
'copy': ["Qid"]
};
ko.mapping.fromJS(data, mapping, this.items);
count = 0;
};
but can't search by key data loaded using mapping plugin
demo: http://jsfiddle.net/RqSDv/
The mapping plugin turns regular properties into observable properties.
So in your indexBy you need to handle the case when your keyName refers to a ko.observable.
When you get the key property value with v[keyName] you need to use ko.utils.unwrapObservable (or ko.unwrap if you using a newer version of KO) to make sure to correctly unwrap your observable property:
ko.observableArray.fn.indexBy = function (keyName) {
var index = ko.computed(function () {
var list = this() || [];
var keys = {};
ko.utils.arrayForEach(list, function (v) {
if (keyName) {
keys[ko.utils.unwrapObservable(v[keyName])] = v;
} else {
keys[v] = v;
}
});
return keys;
}, this);
this.findByKey = function (key) {
return index()[key];
};
return this;
};
Demo JSFiddle.

Setting $scope.items in Angular Binding

I have a service with the following function,
public object Get(AllUsers request)
{
var users = XYZ.GetAllUsers();
var userList = users.Cast<XYZ>();
return new AllUsers
{
UsersAcc = userList.Select(ConvertToEntity).ToList()
};
}
I am trying to get the results from angular controller.
function UserAccountController($scope, $location, $filter, UserAccount) {
#scope.items = function(){
var abc = UserAccount.query();
return abc.UsersAcc
}
}
Here is my Service
angular.module('userAccService', ['ngResource']).factory('UserAcc', function($resource) {
return $resource('/api/useracc/:id', {}, {
query: {
method: 'GET',
}
});
I am new to angular service, and can't seem to make it to work.
You need to create an array object and return it. After the query is done you can populate that same instance with the list UsersAcc. Keep in mind that $scope.items will be [] untill the query returns with data.
$scope.items = getUsersAcc();
function getUsersAcc() {
var dataArray = new Array();
UserAccount.query(function (data) {
var list = data.UsersAcc;
for (var i = 0, c = list.length; i < c; i++) {
dataArray.push(list[i]);
}
};
return dataArray;
};

Resources