How to get data from AngularJS callback function in loopback? - javascript

I want to know how the retrieve "good" array from angular function. I have this function in angular:
app.run(function($rootScope,Communications,$http,$filter) {
$rootScope.getCommunication =
function(object_type,val,id,isType,isSendSms,getNotes){
var array = {};
var newArr = [];
// getting data from mysql data
var myVals = Communications.find({
filter: {
where: {
and : [{
communications_type_code : val
},{
object_id : id
},{
object_type : object_type
}]
}
}
}).$promise
.then(function(data) {
for(var ind=0; ind<data.length; ind++){
array['address_type'] = data[ind].address_type;
array['contact_value'] = data[ind].contact_value;
array['send_sms'] = data[ind].send_sms;
}
newArr.push(array);
return newArr;
});
return newArr;
};
});
When I call to the function in Angular controller like this:
var arr = $rootScope.getCommunication(2,3,$id);
console.log(arr);
I am getting in the console something like this:
When I call to arr[0] I get undefined.
How can i recieve this data?

You need to return the promise, currently you are returning the array before it is updated. Async works by running all the synchronous code first then running anything async.
var arr = []; // runs first
promise.then(function(result){arr = result}) // runs third.
return arr; // runs second
You need to change your code to return the promise. However this also means your calling code has to handle async code.
function asyncFunc() {
return promise.then(function(result){return result});
}
asyncFunc().then(function(result) {console.log(result)}) // output is the value of result.
In the context of the code you gave above
app.run(function($rootScope,Communications,$http,$filter) {
$rootScope.getCommunication =
function(object_type,val,id,isType,isSendSms,getNotes){
// getting data from mysql data
return Communications.find({
filter: {
where: {
and : [{
communications_type_code : val
},{
object_id : id
},{
object_type : object_type
}]
}
}
}).$promise
.then(function(data) {
var array = {};
var newArray = [];
for(var ind=0; ind<data.length; ind++){
array['address_type'] = data[ind].address_type;
array['contact_value'] = data[ind].contact_value;
array['send_sms'] = data[ind].send_sms;
}
newArr.push(array);
return newArr;
});
};
});
and the calling function:
var arr = $rootScope.getCommunication(2,3,$id)
.then(function(arr){console.log(arr)})

You can use callback in following way
app.run(function($rootScope,Communications,$http,$filter) {
$rootScope.getCommunication =
function(object_type,val,id,isType,isSendSms,getNotes, callback){
var array = {};
var newArr = [];
// getting data from mysql data
var myVals = Communications.find({
filter: {
where: {
and : [{
communications_type_code : val
},{
object_id : id
},{
object_type : object_type
}]
}
}
}).$promise
.then(function(data) {
for(var ind=0; ind<data.length; ind++){
array['address_type'] = data[ind].address_type;
array['contact_value'] = data[ind].contact_value;
array['send_sms'] = data[ind].send_sms;
}
newArr.push(array);
//return using callback
return callback(newArr);
});
//return using callback
return callback(newArr);
};
});
And use callback to access result
$rootScope.getCommunication(2,3,$id, function(result){
var arr = result
})

Related

Braintree Transaction.search in Meteor Server

How can I wait for the Braintree Transaction.search() function to return all data.
Right now it does not wait and just comes back with undefined return value.
Here is the code
I tried to use Meteor.asynwrap but that also does not work.
`
function getTrxns(cid) {
var future = new Future();
var trxns = [];
var i = 0
var stream = gateway.transaction.search(function (search) {
r = search.customerId().is(cid)});
stream.on("data", function(data){
i = i+1
trxns.push({
'id':data.id,
'amount':data.amount,
'crtDt': data.createdAt,
'ccType': data.creditCard.cardType,
'currency': data.currencyIsoCode,
'last4': data.creditCard.last4,
'expdt': data.creditCard.expirationDate
});
});
stream.on("end", function(){
// print the output in console
console.log('End Stream cnt: '+i);
return trxns;
});
stream.resume();
}
Meteor.methods({
findCustTrxns: function() {
var btId = Meteor.user().custBtId;
if (!btId) { return []; };
console.log('findCustTrxns cusBtId: '+btId);
var xx = getTrxns(btId);
console.log('xx len :'+xx.length);
}
});
OUTPUT is:
I20170509-15:22:09.095(0)? findCustTrxns cusBtId: 232057823
I20170509-15:22:09.095(0)? Exception while invoking method 'findCustTrxns' TypeError: Cannot read property 'length' of undefined
I20170509-15:22:09.095(0)? End Stream cnt: 56
Found a way to make it work:
1. Added a callback function
function getTrxns(cid,callback )
2. invoked the callback in stream.on('end;..) Here is the code
function getTrxns(cid,callback ) {
var trxns = [];
var i = 0
var stream = gateway.transaction.search(function (search) {
r = search.customerId().is(cid)});
stream.on("data", function(data){
i = i+1
trxns.push({
'id':data.id,
});
});
stream.on("end", function(){
// print the output in console
console.log('End Stream cnt: '+i);
callback('', trxns);
});
stream.resume();
}
3. Changed the Meteor Method :
findCustTrxns: function(btId) {
if (!btId) { return []; };
console.log('findCustTrxns cusBtId: '+btId);
var trxns = [];
var i = 0;
var fn = Meteor.wrapAsync(getTrxns); //made it a synchronous call
try {
var res = fn(btId);
if (res) {
console.log('Got data from getTrxns ');
return res;
}
} catch( err) {
console.log('Error calling hetTrxns '+err);
}
}, //findCustTrxns
Now I am able to get the Transactions. Hope it helps

AngularJs - check if value exists in array object

var SelectedOptionId = 957;
$scope.array = [{"957":"1269"},{"958":"1265"},{"956":"1259"},{"957":"1269"},{"947":"1267"}]
Is there a way of checking if a value exists in an that kind of array objects. I am using Angular and underscore.
I have tried all this -
if ($scope.array.indexOf(SelectedOptionId) === -1) {console.log('already exists')}
and
console.log($scope.array.hasOwnProperty(SelectedOptionId)); //returns false
and
console.log(_.has($scope.array, SelectedOptionId)); //returns false
You could use Array#some and check with in operator.
exists = $scope.array.some(function (o) {
return SelectedOptionId in o;
});
Check this
function checkExists (type) {
return $scope.array.some(function (obj) {
return obj === type;
}
}
var chkval=checkExists("your value")
Try this:
if($scope.array[SelectedOptionId] || _.includes(_.values($scope.array, SelectedOptionId))) { }
That should cover both a key and a value.
let selectedOptionId = "957";
let array = [{"957":"1269"},{"958":"1265"},{"956":"1259"},{"957":"1269"},{"947":"1267"}];
let filtered = array.filter(function(element){
return Object.keys(element)[0] === selectedOptionId;
});
console.log(filtered);
console.log(_.some($scope.array, function(o) { return _.has(o, "957"); }));
using underscore
You can use filter for this. The following code should return you output array with matching results, if it exists, otherwise it will return an empty array :
var array = [{"957":"1269"},{"958":"1265"},{"956":"1259"},{"957":"1269"},{"947":"1267"}];
var SelectedOptionId = 957;
var result = array.filter(
function(item) {return item[SelectedOptionId]}
)
console.log(result);
For your input it returns:
[ { '957': '1269' }, { '957': '1269' } ]
You can do it using the in operator or the hasOwnProperty function, to check for the existence of a key in an object inside the given array.
The way you've tried using hasOwnProperty function didn't work because you were checking it directly on the array instead of checking against the items in the array.
Check the below code snippet.
angular
.module('demo', [])
.controller('HomeController', DefaultController);
function DefaultController() {
var vm = this;
vm.items = [{
"957": "1269"
}, {
"958": "1265"
}, {
"956": "1259"
}, {
"957": "1269"
}, {
"947": "1267"
}];
var key = '957';
var isExists = keyExists(key, vm.items);
console.log('is ' + key + ' exists: ' + isExists);
function keyExists(key, items) {
for (var i = 0; i < items.length; i++) {
// if (key in items[i]) {
if (items[i].hasOwnProperty(key)) {
return true;
}
}
return false;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demo">
<div ng-controller="HomeController as home">
{{home.items | json}}
</div>
</div>
Different ways to do this :
Using Object hasOwnProperty() method.
Working demo :
var SelectedOptionId = 957;
var arrayObj = [{"957":"1269"},{"958":"1265"},{"956":"1259"},{"957":"1269"},{"947":"1267"}];
function checkOption(key) {
for(var i in arrayObj) {
if(arrayObj[i].hasOwnProperty(key) == true) {
return key+" exists.";
} else {
return key+" Not exists.";
}
}
};
console.log(checkOption(SelectedOptionId)); // 957 exists.
using Array filter() method.
Working demo :
var SelectedOptionId = 957;
var arrayObj = [{"957":"1269"},{"958":"1265"},{"956":"1259"},{"957":"1269"},{"947":"1267"}];
var result = arrayObj.filter(function(elem) {
return elem[SelectedOptionId]
});
if(result == '') {
console.log(SelectedOptionId+" not exists.");
} else {
console.log(SelectedOptionId+" exists.");
}
using Array some() method as suggested by Nina Scholz.
Working demo :
var SelectedOptionId = 957;
var arrayObj = [{"957":"1269"},{"958":"1265"},{"956":"1259"},{"957":"1269"},{"947":"1267"}];
var result = arrayObj.some(function (o) {
return SelectedOptionId in o;
});
if(result == '') {
console.log(SelectedOptionId+" not exists.");
} else {
console.log(SelectedOptionId+" exists.");
}

Finding Item in JSON Array and adding it to another Array. Javascript

Having some issues with finding an item in a JSON Array and passing it to a different array. The error I am getting appears to be that it's not properly passing the item out of the function. It is finding the item in the database, I can see it properly in console logs and view it properly with JSON.stringify.
Though, no matter how I have tried passing it out of the function (as a string, as an object etc.) it is not returning a value besides undefined.
If I do a console.log on newCard it will always come back as undefined.
Any help on this would be greatly appreciated, thank you.
var deckObject = [];
var newCard = findCard('EX1_123');
deckObject.push(newCard);
function findCard(cardId){
$.each(cardDB, function(i, v) {
if (v.id === cardId) {
v['count'] = 1;
return v;
}
});
}
you should never return value from loop, rather use callback to manage asynchronous code
var deckObject = [];
var newCard = findCard('EX1_123',function(newcard){
deckObject.push(newCard);
});
function findCard(cardId,callback){
$.each(cardDB, function(i, v) {
if (v.id === cardId) {
v['count'] = 1;
callback(v);
}
});
}
$.each doesn't return out of the function. Assign the returned value to a vraible and then return it.
function findCard(cardId){
var res = $.each(cardDB, function(i, v) {
if (v.id === cardId) {
console.log(v.id);
v['count'] = 1;
return v;
}
});
return res;
}
Sample Snippet.
$(function(){
var cardDB = [
{
id: '1',
count: 0
},
{
id: '2',
count: 0
},
{
id: '3',
count: 0
}
]
var deckObject = [];
var newCard = findCard('1');
console.log(newCard);
deckObject.push(newCard);
function findCard(cardId){
var opt = $.each(cardDB, function(i, v) {
if (v.id === cardId) {
console.log(v.id);
v['count'] = 1;
return v;
}
});
return opt;
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Node JS return within nested function

I am trying to return the value of itemInfo[0] from within this nested function. Can anyone help how I should return this value with a callback ?
function findItem(item) {
var itemInfo = [];
Item.findItem(item, function(err, itemInfo){
itemInfo[0].info = _.unescape(itemInfo[0].info);
itemInfo[0].title = _.unescape(itemInfo[0].title);
// console.log(itemInfo[0]);
return itemInfo[0];
});
};
Set the cb argument to null after you use it and check for its validity before calling.
function findItem(item, cb) {
var itemInfo = [];
Item.findItem(item, function(err, itemInfo){
if (cb) {
itemInfo[0].info = _.unescape(itemInfo[0].info);
itemInfo[0].title = _.unescape(itemInfo[0].title);
// console.log(itemInfo[0]);
cb( itemInfo[0] );
cb = null;
}
});
};
What if you returned the returned value?
function findItem(item) {
var itemInfo = [];
return Item.findItem(item, function(err, itemInfo){
itemInfo[0].info = _.unescape(itemInfo[0].info);
itemInfo[0].title = _.unescape(itemInfo[0].title);
// console.log(itemInfo[0]);
return itemInfo[0];
});
};

Find an element in an array recursively

I have an array of objects. Every object in the array has an id and an item property that is an array containing other object. I need to be able to find an element in an array by id. Here is a sample of what I have done so far, but the recursive function is always returning undefined.
How can I quit the function and return the item when I have called the function recursively several times?
$(function () {
var treeDataSource = [{
id: 1,
Name: "Test1",
items: [{
id: 2,
Name: "Test2",
items: [{
id: 3,
Name: "Test3"
}]
}]
}];
var getSubMenuItem = function (subMenuItems, id) {
if (subMenuItems && subMenuItems.length > 0) {
for (var i = 0; i < subMenuItems.length; i++) {
var item;
if (subMenuItems[i].Id == id) {
item = subMenuItems[i];
return item;
};
getSubMenuItem(subMenuItems[i].items, id);
};
};
};
var searchedItem = getSubMenuItem(treeDataSource, 3);
alert(searchedItem.id);
});
jsFiddle
You should replace
getSubMenuItem(subMenuItems[i].items, id);
with
var found = getSubMenuItem(subMenuItems[i].items, id);
if (found) return found;
in order to return the element when it is found.
And be careful with the name of the properties, javascript is case sensitive, so you must also replace
if (subMenuItems[i].Id == id) {
with
if (subMenuItems[i].id == id) {
Demonstration
Final (cleaned) code :
var getSubMenuItem = function (subMenuItems, id) {
if (subMenuItems) {
for (var i = 0; i < subMenuItems.length; i++) {
if (subMenuItems[i].id == id) {
return subMenuItems[i];
}
var found = getSubMenuItem(subMenuItems[i].items, id);
if (found) return found;
}
}
};
I know its late but here is a more generic approach
Array.prototype.findRecursive = function(predicate, childrenPropertyName){
if(!childrenPropertyName){
throw "findRecursive requires parameter `childrenPropertyName`";
}
let array = [];
array = this;
let initialFind = array.find(predicate);
let elementsWithChildren = array.filter(x=>x[childrenPropertyName]);
if(initialFind){
return initialFind;
}else if(elementsWithChildren.length){
let childElements = [];
elementsWithChildren.forEach(x=>{
childElements.push(...x[childrenPropertyName]);
});
return childElements.findRecursive(predicate, childrenPropertyName);
}else{
return undefined;
}
}
to use it:
var array = [<lets say an array of students who has their own students>];
var joe = array.findRecursive(x=>x.Name=="Joe", "students");
and if you want filter instead of find
Array.prototype.filterRecursive = function(predicate, childProperty){
let filterResults = [];
let filterAndPushResults = (arrayToFilter)=>{
let elementsWithChildren = arrayToFilter.filter(x=>x[childProperty]);
let filtered = arrayToFilter.filter(predicate);
filterResults.push(...filtered);
if(elementsWithChildren.length){
let childElements = [];
elementsWithChildren.forEach(x=>{
childElements.push(...x[childProperty]);
});
filterAndPushResults(childElements);
}
};
filterAndPushResults(this);
return filterResults;
}

Categories