Transfer data from factory to controller - javascript

Somehow I am not able to get my data from the factory method to the controller. I am using javascript remoting and factory is given below
function userRecordFetchFactory($rootScope) {
var custRec = {};
return {
checkRecordType : function(urlObject) {
function loadRecordType(err, records, event) {
if (err) {
displayReadingInformationErrorView();
} else if (records != null && records.length == 0) {
displayReadingInformationErrorView();
} else {
custRec = {
Name : records[0].get('Name'),
lat : records[0].get('Latitude__c'),
lon : records[0].get('Longitude__c'),
SiteStreet : records[0]
.get('SiteStreet__c'),
SiteCity : records[0].get('SiteCity__c'),
SiteCountryCode : records[0]
.get('SiteCountryCode__c'),
SitePostalCode : records[0]
.get('SitePostalCode__c'),
AddressID : records[0].get('AddressID__c'),
loaded : true
};
}
}
if (urlObject && urlObject.aid
&& urlObject.aid.startsWith(accPrefix)) {
objModel = new RemoteObjectModel.Account();
}
if (urlObject && urlObject.aid
&& urlObject.aid.startsWith(leadPrefix)) {
objModel = new RemoteObjectModel.Lead();
}
if (objModel) {
objModel.retrieve({
where : {
Id : {
eq : urlObject.aid
}
}
}, loadRecordType);
}
return custRec;
}
};
}
and my controller is given below to access the data
function LocatorInitController($document, $scope,
userRecordFetchFactory) {
console.log("inside the controller"+urlParams);
$scope.CustomerSite = {};
userRecordFetchFactory.checkRecordType(urlParams)
.then(function successData(data){
$scope.CustomerSite = data.data;
execGeoCoding();
});
I get an error cannot read property success of undefined. In the factory the method checkRecordType has a retrieve function which is a javascript remoting call and that finction has a callback to loadrecordtype.

Suggest you write your factory in a simpler way to read it. All your nesting is causing you not to see the whole thing easily
Put all the accessible members up top
// pass functions as references to object properties
// can easily see the whole factory object at top of the file
var custRec = {
checkRecordType : checkRecordType,
subscribe : subscribe
};
return custRec;
// move function declarations to the bottom and out of the way
function checkRecordType(){
/// do stuff
return stuff;
}
function loadRecordType(err, records, event) {
/// do stuff
return stuff;
}
function subscribe(scope, callback){
/// do stuff
return stuff;
}
See John Papa Angular STyle Guide

Why don't you try rewriting your factory like so:
function Factory() {
var custRec = {
subscribe: function(scope, callback) {
var handler = $rootScope.$on(
'fire-event-accountservice-retrieve',
function(
event, data) {
callback(data);
scope.$apply();
});
scope.$on('$destroy', handler);
},
checkRecordType: function(urlObject) {
var custRec;
if (urlObject.aid == null && urlObject.addr == null) {
displayCurrentLocation();
}
if (urlObject && urlObject.aid &&
urlObject.aid.startsWith(accPrefix)) {
objModel = new RemoteObjectModel.Account();
}
if (urlObject && urlObject.aid &&
urlObject.aid.startsWith(leadPrefix)) {
objModel = new RemoteObjectModel.Lead();
}
if (objModel == null && urlObject.aid != null && urlObject.addr == null) {
displayReadingInformationErrorView();
}
if (objModel) {
objModel.retrieve({
where: {
Id: {
eq: urlObject.aid
}
}
}, loadRecordType);
} else if ((urlObject.addr != null || urlObject.addr != '') && (typeof urlObject.addr != "undefined")) {
displayLocationBasedOnAddress(urlObject.addr);
}
function loadRecordType(err, records, event) {
if (err) {
displayReadingInformationErrorView();
} else if (records != null && records.length == 0) {
displayReadingInformationErrorView();
} else {
custRec = {
Name: records[0].get('Name'),
lat: records[0].get('Latitude__c'),
lon: records[0].get('Longitude__c'),
SiteStreet: records[0]
.get('SiteStreet__c'),
SiteCity: records[0].get('SiteCity__c'),
SiteCountryCode: records[0]
.get('SiteCountryCode__c'),
SitePostalCode: records[0]
.get('SitePostalCode__c'),
AddressID: records[0].get('AddressID__c'),
loaded: true
};
/* $rootScope.$emit(
'fire-event-accountservice-retrieve',
custRec); */
}
}
}
}
return custRec;
}
Looks like you're returning your factory object the wrong way.

function userRecordFetchFactory($rootScope) {
var custRec = {};
custRec.checkRecordType = function (urlObject) {
function loadRecordType(err, records, event) {
if (err) {
displayReadingInformationErrorView();
} else if (records != null && records.length == 0) {
displayReadingInformationErrorView();
} else {
custRec = {
Name: records[0].get('Name'),
lat: records[0].get('Latitude__c'),
lon: records[0].get('Longitude__c'),
SiteStreet: records[0]
.get('SiteStreet__c'),
SiteCity: records[0].get('SiteCity__c'),
SiteCountryCode: records[0]
.get('SiteCountryCode__c'),
SitePostalCode: records[0]
.get('SitePostalCode__c'),
AddressID: records[0].get('AddressID__c'),
loaded: true
};
}
}
if (urlObject && urlObject.aid
&& urlObject.aid.startsWith(accPrefix)) {
objModel = new RemoteObjectModel.Account();
}
if (urlObject && urlObject.aid
&& urlObject.aid.startsWith(leadPrefix)) {
objModel = new RemoteObjectModel.Lead();
}
if (objModel) {
objModel.retrieve({
where: {
Id: {
eq: urlObject.aid
}
}
},
return custRec;
}

Related

Where to register Handlebars Helper?

working currently with a code base that I'm not familiar with and I'm trying to instantiate some comparison operators with Handlebars.js that's already in place. Where can I add this registerHelper to the JS file?
Helper I need to register:
Handlebars.registerHelper('ifCond', function(v1, v2, options) {
if(v1 === v2) {
return options.fn(this);
}
return options.inverse(this);
});
Area I think I need to put it?
function HandlebarsEnvironment(helpers, partials, decorators) {
this.helpers = helpers || {};
this.partials = partials || {};
this.decorators = decorators || {};
_helpers.registerDefaultHelpers(this);
_decorators.registerDefaultDecorators(this);
}
HandlebarsEnvironment.prototype = {
constructor: HandlebarsEnvironment,
logger: _logger2['default'],
log: _logger2['default'].log,
registerHelper: function registerHelper(name, fn) {
if (_utils.toString.call(name) === objectType) {
if (fn) {
throw new _exception2['default']('Arg not supported with multiple helpers');
}
_utils.extend(this.helpers, name);
} else {
this.helpers[name] = fn;
}
},
unregisterHelper: function unregisterHelper(name) {
delete this.helpers[name];
},
registerPartial: function registerPartial(name, partial) {
if (_utils.toString.call(name) === objectType) {
_utils.extend(this.partials, name);
} else {
if (typeof partial === 'undefined') {
throw new _exception2['default']('Attempting to register a partial called "' + name + '" as undefined');
}
this.partials[name] = partial;
}
},
unregisterPartial: function unregisterPartial(name) {
delete this.partials[name];
},
Thanks for your help.

How to add multiple key and value for search object array

I have function code for search data in array, it goes well but in one key and one value. what I want is an array search with multiple key and value, ​​that work like query and in sql.
My question: How to add multiple key and value in my function code?
Array Data:
[{
"id": 1,
"name": "John",
"addres": {
"code": 1,
"status": 1
}
},
{
"id": 2,
"name": "Jery",
"addres": {
"code": 2,
"status": 1
}
}
]
My Function code:
function where(prop, value) {
var filtered = [], checkStatus = 0;
for (var i = 0; i < data.length; i++) {
var obj = data[i];
for (var key in obj) {
var item = obj[key];
if (typeof(obj[key] == "object")) {
if (item[prop] == value) {
checkStatus = 1;
filtered.push(obj);
}
if (typeof(value) == "string") {
if (item[prop] != undefined
&& item[prop].toLowerCase().includes(value.toLowerCase())) {
checkStatus = 1;
filtered.push(obj);
}
}
}
}
if (checkStatus == 0 && obj[prop] != undefined) {
if (obj[prop] == value) {
filtered.push(obj);
}
if (typeof(obj[prop]) == 'string') {
if (obj[prop] != undefined
&& obj[prop].toLowerCase().includes(value.toLowerCase())) {
filtered.push(obj);
}
}
}
}
return filtered;
}
Its work when where('status',1) but what i want where(['id','status'],[2,1])
Sorry everyone, I tried and was successful
function where(value) {
var result = data.filter(function(o) {
return Object.keys(value).every(function(p) {
if (typeof(o[p]) == 'object') {
return Object.keys(value[p]).some(function(opo) {
if (typeof(value[p][opo]) == 'string') {
return o[p][opo].toLowerCase().includes(value[p][opo].toLowerCase());
} else {
return o[p][opo] == value[p][opo];
}
});
} else if (typeof(o[p]) == 'string') {
return o[p].toLowerCase().includes(value[p].toLowerCase());
} else {
return o[p] == value[p];
}
});
});
return result;
}
Thank you for giving me advice on using object, for calling where({id:2,addres:{status:1}})

Modify a cleaning JSON object javascript function

So, this is my function that deletes empty and null properties from a JSON object in Javascript. I need the function to delete also empty nested objects but its not doing it right now. I have tried but failed several times to modify this function ( I got this from an old post in this site ).
Can someone help me with this?
Function
function clean_object(test, recurse) {
for (var i in test) {
if (test[i] === null || test[i] == "" ) {
delete test[i];
} else if (recurse && typeof test[i] === 'object' ) {
clean_object(test[i], recurse);
}
}
}
Object before cleaning
{ "data.openstack.public_ipv4": "falseip" }
Object after cleaning
{"data":{"openstack":{}}}
What I need
{}
Thanks in advance!
With the first development step as provided as a partial approach I just wanted to make the example(s) work in a way that it clears all of an objects null values and zero-length string-values ...
function clearEmptyValuesRecursively(obj) {
if (Array.isArray(obj)) {
obj.forEach(function (item) {
clearEmptyValuesRecursively(item);
});
} else {
Object.keys(obj).forEach(function (key) {
var value = obj[key];
if ((value === null) || (value === '')) {
delete obj[key];
} else if (typeof value !== 'string') {
clearEmptyValuesRecursively(value);
}
});
}
return obj;
}
var data = {
"data": {
"openstack": {},
"fullstack": "fullstack",
"emptyString": ""
},
"emptyData": null
};
console.log('data - before : ', JSON.stringify(data));
clearEmptyValuesRecursively(data);
console.log('data - after : ', JSON.stringify(data));
data = {
"data": {
"openstack": {}
}
};
console.log('data - before : ', JSON.stringify(data));
clearEmptyValuesRecursively(data);
console.log('data - after : ', JSON.stringify(data));
.as-console-wrapper { max-height: 100%!important; top: 0; }
... within the second step I kind of recycled the above approach. This time the recursively working function was build for mainly clearing empty main (data) structures like {} and [], but it also takes care of deleting empty values as already shown with the first approach. Altogether this also is what the OP did ask for ...
function clearEmptyStructuresRecursively(obj) {
function isEmptyStructure(type) {
return ((Object.keys(type).length === 0) || (Array.isArray(type) && (type.length === 0)));
}
function isEmptyValue(type) {
return ((type == null) || (type === '')); // undefined or null or zero length string value.
}
if (Array.isArray(obj)) {
obj.forEach(function (item) {
clearEmptyStructuresRecursively(item);
});
} else if (obj && (typeof obj !== 'string')) {
Object.keys(obj).forEach(function (key) {
var value = obj[key];
if (isEmptyValue(value) || isEmptyStructure(value)) {
delete obj[key]; // ... delete ... and step into recursion ...
clearEmptyStructuresRecursively(obj);
}
clearEmptyStructuresRecursively(value);
});
Object.keys(obj).forEach(function (key) {
var value = obj[key];
if (isEmptyValue(value) || isEmptyStructure(value)) {
delete obj[key]; // ... final delete.
}
});
}
return obj;
}
var data = {
"data": {
"openstack": {}
}
};
console.log('data - before : ', JSON.stringify(data));
clearEmptyStructuresRecursively(data);
console.log('data - after : ', JSON.stringify(data));
data = {
"data": {
"openstack": {},
"fullstack": "fullstack",
"emptyString": ""
},
"emptyData": null
};
console.log('data - before : ', JSON.stringify(data));
clearEmptyStructuresRecursively(data);
console.log('data - after : ', JSON.stringify(data));
.as-console-wrapper { max-height: 100%!important; top: 0; }

Titanium Alloy Backbone and ACS

I'm trying to pass data from Appcelerator Cloud Services to Backbone models. I couldn't find documentation on how to do this...
Below is the config from my model file:
exports.definition = {
config: {
"columns": {
"id":"integer",
"address":"text",
"user_completed":"integer"
},
"adapter": {
"type": "", //what can I enter?
"collection_name": "places"
}
},
extendModel : function(Model) {
_.extend(Model.prototype, {
validate : function(attrs) {
for (var key in attrs) {
var value = attrs[key];
if (value) {
if (key === "item") {
if (value.length <= 0) {
return 'Error: No item!';
}
}
if (key === "done") {
if (value.length <= 0) {
return 'Error: No completed flag!';
}
}
}
}
}
});
return Model;
},
extendCollection : function(Collection) {
_.extend(Collection.prototype, {
comparator: function(places) {
return places.get('done');
}
});
return Collection;
}
};
How can I pass data from ACS?
You need to use "acs" in your config.
Check this :
exports.definition = {
config: {
"columns": {
"id":"integer",
"address":"text",
"user_completed":"integer"
},
"adapter": {
"type": "acs", // Use "acs"
"collection_name": "places"
}
},
extendModel : function(Model) {
_.extend(Model.prototype, {
validate : function(attrs) {
for (var key in attrs) {
var value = attrs[key];
if (value) {
if (key === "item") {
if (value.length <= 0) {
return 'Error: No item!';
}
}
if (key === "done") {
if (value.length <= 0) {
return 'Error: No completed flag!';
}
}
}
}
}
});
return Model;
},
extendCollection : function(Collection) {
_.extend(Collection.prototype, {
comparator: function(places) {
return places.get('done');
}
});
return Collection;
}
};
Check this presentation : Titanium presentation under ACS topic with "ACS in Alloy" header.
Also , here is sample example : Alloy backbone & ACS
Hope this helps.

Meteor Collection.allow

Hey guys agian i have a a problem with Meteor accounts api.
im trying to let only users that are logged in to change their own list, without effecting other users list here is my code:
client-side:
Meteor.subscribe('Categories');
Meteor.autosubscribe(function() {
Meteor.subscribe("listdetails",
Session.get('current_list'));
});
'keyup #add-category': function (e,t){
if (e.which === 13)
{
var catVal = String(e.target.value || "");
if (catVal)
{
lists.insert({Category:catVal,owner:this.userId});
Session.set('adding_category', false);
}
}
},
the server-side:
Meteor.startup(function () {
Meteor.publish("Categories", function() {
return lists.find({owner:Meteor.userId},{fields:{Category:1}});
});
Meteor.publish("listdetails", function(category_id){
return lists.find({_id:category_id});
});
});
both sides(client and server):
lists = new Meteor.Collection("Lists");
/*function adminUser(userId) {
var adminUser = Meteor.users.findOne({username:"boazhoch"});
return userId && adminUser && userId === adminUser._id;
} */
function adminUser(userId) {
var adminUser = Meteor.users.findOne({username:"admin"});
return (userId && adminUser && userId === adminUser._id);
}
lists.allow({
insert: function (userId, doc) {
// the user must be logged in, and the document must be owned by the user
return (adminUser(userId) || userId && doc.owner === userId);
},
update: function(userId, docs, fields, modifier){
return adminUser(userId) || _.all(docs, function(doc) {
return doc.owner === userId;
});
},
remove: function (userId, docs){
return adminUser(userId) || _.all(docs, function(doc) {
return doc.owner === userId;
});
},
fetch: ['owner']
});
you can clearly see that when logged in with admin and not logged the screens are similar (not the result i want) and notice that this.userId is "undefined" which is wired and this is why i used Meteor.userId.
Change your code to this below:
client (in the "keyup #add-category" event):
lists.insert({Category:catVal,owner:Meteor.userId()});
server (in publish Categories):
return lists.find({owner:this.userId},{fields:{Category:1}});
both sides(client and server):
lists.allow({
insert: function(userId, doc){
return adminUser(userId) || (userId && doc.owner === userId);
},
update: function(userId, doc, fields, modifier) {
return adminUser(userId) || doc.owner === userId;
},
remove: function (userId, doc){
return adminUser(userId) || doc.owner === userId;
},
fetch: ['owner']
});
On the client you should use Meteor.userId() and on the server this.userId, but only in a publish function:
Meteor.publish("Categories", function() {
return lists.find({owner:this.userId},{fields:{Category:1}});
});
And when you insert it, on the client:
lists.insert({Category:catVal,owner:Meteor.userId()});
You also need to make sure you remove autopublish, which automatically publishes everything, before you start meteor
meteor remove autopublish
full client code:
Meteor.subscribe('Categories');
Meteor.autosubscribe(function() {
Meteor.subscribe("listdetails",
Session.get('current_list'));
});
Template.categories.lists = function () {
return lists.find({},{sort: {Category: 1}});
};
Session.set('adding_category', false);
Template.categories.new_cat = function () {
return Session.equals('adding_category',true);
};
Template.categories.events({
'click #btnNewCat': function (e, t) {
Session.set('adding_category', true);
Meteor.flush();
focusText(t.find("#add-category"));
},
'keyup #add-category': function (e,t){
if (e.which === 13)
{
var catVal = String(e.target.value || "");
if (catVal)
{
lists.insert({Category:catVal,owner:Meteor.userId});
Session.set('adding_category', false);
}
}
},
'focusout #add-category': function(e,t){
Session.set('adding_category',false);
},
'click .category': selectCategory
});
/////Generic Helper Functions/////
//this function puts our cursor where it needs to be.
function focusText(i,val) {
i.focus();
i.value = val ? val : "";
i.select();
};//< -----This is the end tag for focusText() -----
function selectCategory(e,t){
Session.set('current_list',this._id);
}
function addItem(list_id,item_name){
if (!item_name&&!list_id)
return;
lists.update({_id:list_id},
{$addToSet:{items:{Name:item_name}}});
}
function removeItem(list_id,item_name){
if (!item_name&&!list_id)
return;
lists.update({_id:list_id},
{$pull:{items:{Name:item_name}}});
}
function updateLendee(list_id,item_name,lendee_name){
var l = lists.findOne({"_id":list_id ,
"items.Name":item_name});
if (l&&l.items)
{
for (var i = 0; i<l.items.length; i++)
{
if (l.items[i].Name === item_name)
{
l.items[i].LentTo = lendee_name;
}
}
lists.update({"_id":list_id},{$set:{"items":l.items}});
}
};
Template.list.items = function () {
if (Session.equals('current_list',null)) return null;
else
{
var cats = lists.findOne({_id:Session.get('current_list')});
if (cats&&cats.items)
{
for(var i = 0; i<cats.items.length;i++) {
var d = cats.items[i]; d.Lendee = d.LentTo ? d.LentTo :
"free"; d.LendClass = d.LentTo ?
"label-important" : "label-success";
}
return cats.items;
}
}
};// < ---- ending bracket for Template.list.items function ----
Template.list.list_selected = function() {
return ((Session.get('current_list')!=null) &&
(!Session.equals('current_list',null)));
};
Template.categories.list_status = function(){
if (Session.equals('current_list',this._id))
return "";
else
return " btn-inverse";
};
Template.list.list_adding = function(){
return (Session.equals('list_adding',true));
};
Template.list.lendee_editing = function(){
return (Session.equals('lendee_input',this.Name));
};
Template.list.events({
'click #btnAddItem': function (e,t){
Session.set('list_adding',true);
Meteor.flush();
focusText(t.find("#item_to_add"));
},
'keyup #item_to_add': function (e,t){
if (e.which === 13)
{
addItem(Session.get('current_list'),e.target.value);
Session.set('list_adding',false);
}
},
'focusout #item_to_add': function(e,t){
Session.set('list_adding',false);
},
'click .delete_item': function(e,t){
removeItem(Session.get('current_list'),e.target.id);
},
'click .lendee' : function(e,t){
Session.set('lendee_input',this.Name);
Meteor.flush();
focusText(t.find("#edit_lendee"),this.LentTo);
},
'keyup #edit_lendee': function (e,t){
if (e.which === 13)
{
updateLendee(Session.get('current_list'),this.Name,
e.target.value);
Session.set('lendee_input',null);
}
if (e.which === 27)
{
Session.set('lendee_input',null);
}
}
});
Accounts.ui.config({
passwordSignupFields: 'USERNAME_AND_OPTIONAL_EMAIL'
});

Categories