I am trying an angular program but cant return the right value:
function facilityChecked(facility, search) {
var result;
search.filter(
function (v) {
var rtn = (v["facility_Item"]["text"] == facility);
if (rtn) {
var checked = (v.inherit_To_Service === 'true');
result = checked;
}
else {
result = false;
}
}
);
return result;
}
In the code below $scope.parking should be true and $scope.toilet should be false however they both return as false?
parking = facilityChecked('Parking', rtn.Organisation.Facility);
$scope.parking = parking;
toilet = facilityChecked('Toilet', rtn.Organisation.Facility);
$scope.toilet = toilet;
See also this plunkr link
This function is using filter which loops through each item in the array, so it is always setting result to the value of the last item in the array...
so init result to start, and if the value is found, then parse it out of the item
function facilityChecked(facility, search) {
var result = false;
search.filter(
function (v) {
var rtn = (v["facility_Item"]["text"] == facility);
if (rtn) {
var checked = (v.inherit_To_Service === 'true');
result = checked;
}
}
);
return result;
}
Here the problem is with else part in search.filter(); Actually, search.filter() function is executing for all the Json objects.So, it stores and returns the last object value i.e false".
I think, else part is not necessary, because you taking the values from data.json.
function facilityChecked(facility, search) {
var result;
search.filter(
function(v) {
var rtn = (v["facility_Item"]["text"] == facility);
if (rtn) {
var checked = (v.inherit_To_Service === 'true');
result = checked;
}
}
);
return result;
}
Updated Plunker:http://plnkr.co/edit/SETl5Zqapsdp8FmB6t56?p=preview
Related
I want to avoid reading the previous objects pushed in the JSON array. As shown in the image.
I'm Self learning these concepts. so i need help, about is this the right method to add and read values.
Also i dont know how to ask this question technically. so i would appreciate if someone would tell me how this question should be asked. So that i can atleast improve it for better understanding.
JQUERY
$("#click").click(function(event)
{
event.preventDefault();
var $form = $('#myform');
var $boxes =$("input[id=myCheckboxes]:checked").length;
if($boxes==0)
{
alert("Choose atleast one Category");
}
else if($form.valid() && $boxes>0)
{
//if form is valid action is performed
var data = $( "#myform" ).serializeArray();//serialize the data
var valuesArray = $('input:checkbox:checked').map( function() {
return this.value;
}).get().join(",");
data.push({ name: 'panel', value: valuesArray});
//convert json array into object
var loginFormObject = {};
$.each(data,
function(i, v) {
loginFormObject[v.name] = v.value;
});
array.push(loginFormObject);
alert("Added Successfully");
viewFunction(array);
return false;
}
})
//view function
function viewFunction(array)
{
console.log(array);
var panel_arr = ["", "Regular", "Reduced Fee", "Limited Assurance","Court Programs"];
var ul_block = $("<ul/>");
$.each(array, function(i, data)
{
var panels = data.panel.split(",");
var uli_block = $("<ul/>");
$.each(panels, function(j, jdata)
{
var ulii_block = $("<ul/>");
$edit = $('<a/>').attr('href', 'javascript:;').addClass('btn btn-default active').attr('role', 'button').text('Edit')
.css('margin-left', 5);
$del = $('<a/>').addClass('btn btn-default active').attr('role', 'button').text('Delete')
.css('margin-left', 5);
$(ulii_block).append($("<li/>").html(data.ptitle).append($edit,$del));
$(uli_block).append($("<li/>").html('<span class="Collapsable">'+panel_arr[panels[j]]+'</span>')).append(ulii_block);
$edit.click(editFunction.bind(null, data));//bind data to function
});
$(ul_block).append($("<li/>").html('<span class="Collapsable">'+data.gpanel+'</span>').append(uli_block));
});
$("#addMember").append(ul_block);
$(".Collapsable").click(function () {
$(this).parent().children().toggle();
$(this).toggle();
});
$(".Collapsable").each(function(){
$(this).parent().children().toggle();
$(this).toggle();
});
}
i made this method to compare between 2 of my json objects:
//tempObj is old object and newObj is well your new JSON, this function returns bool
function isDifferentObj(tempObj, newObj) {
var tempObjLength = Object.keys(tempObj).length;
var newObjLength = Object.keys(newObj).length;
if (newObjLength >= tempObjLength) {
for (var key in newObj) {
if (typeof tempObj[key] != "undefined") {
if (newObj[key] != tempObj[key]) {
return true;
}
} else {
return true;
}
}
return false;
} else {
for (var key in tempObj) {
if (typeof newObj[key] != "undefined") {
if (tempObj[key] != newObj[key]) {
return true;
}
} else {
return true;
}
}
return false;
}
}
After a lot of trouble i found my problem. I was appending the result every time.
The code line which was making the trouble was this.
$("#addMember").append(ul_block);
I changed it to
$("#addMember").html(ul_block);
hence avoiding duplicates.
I have been trying to translate my code from es6 to es5 because of some framework restrictions at my work... Although I have been quite struggling to locate what the problem is. For some reason the code does not work quite the same, and there is no errors either ...
Can someone tell me If I have translated properly ?
This is the ES6 code :
function filterFunction(items, filters, stringFields = ['Title', 'Description'], angular = false) {
// Filter by the keys of the filters parameter
const filterKeys = Object.keys(filters);
// Set up a mutable filtered object with items
let filtered;
// Angular doesn't like deep clones... *sigh*
if (angular) {
filtered = items;
} else {
filtered = _.cloneDeep(items);
}
// For each key in the supplied filters
for (let key of filterKeys) {
if (key !== 'TextInput') {
filtered = filtered.filter(item => {
// Make sure we have something to filter by...
if (filters[key].length !== 0) {
return _.intersection(filters[key], item[key]).length >= 1;
}
return true;
});
}
// If we're at TextInput, handle things differently
else if (key === 'TextInput') {
filtered = filtered.filter(item => {
let searchString = "";
// For each field specified in the strings array, build a string to search through
for (let field of stringFields) {
// Handle arrays differently
if (!Array.isArray(item[field])) {
searchString += `${item[field]} `.toLowerCase();
} else {
searchString += item[field].join(' ').toLowerCase();
}
}
// Return the item if the string matches our input
return searchString.indexOf(filters[key].toLowerCase()) !== -1;
});
}
}
return filtered;
}
And this is the code I translated that partially 99% work ..
function filterFunction(items, filters, stringFields, angular) {
// Filter by the keys of the filters parameter
var filterKeys = Object.keys(filters);
// Set up a mutable filtered object with items
var filtered;
// Angular doesn't like deep clones... *sigh*
if (angular) {
filtered = items;
} else {
filtered = _.cloneDeep(items);
}
// For each key in the supplied filters
for (var key = 0 ; key < filterKeys.length ; key ++) {
if (filterKeys[key] !== 'TextInput') {
filtered = filtered.filter( function(item) {
// Make sure we have something to filter by...
if (filters[filterKeys[key]].length !== 0) {
return _.intersection(filters[filterKeys[key]], item[filterKeys[key]]).length >= 1;
}
return true;
});
}
// If we're at TextInput, handle things differently
else if (filterKeys[key] === 'TextInput') {
filtered = filtered.filter(function(item) {
var searchString = "";
// For each field specified in the strings array, build a string to search through
for (var field = 0; field < stringFields.length; field ++) {
// Handle arrays differently
console.log(field);
if (!Array.isArray(item[stringFields[field]])) {
searchString += item[stringFields[field]] + ' '.toLowerCase();
} else {
searchString += item[stringFields[field]].join(' ').toLowerCase();
}
}
// Return the item if the string matches our input
return searchString.indexOf(filters[filterKeys[key]].toLowerCase()) !== -1;
});
}
}
return filtered;
}
These two lines
searchString += `${item[field]} `.toLowerCase();
searchString += item[stringFields[field]] + ' '.toLowerCase();
are not equivalent indeed. To apply the toLowerCase method on all parts of the string, you'll need to wrap the ES5 concatenation in parenthesis:
searchString += (item[stringFields[field]] + ' ').toLowerCase();
or, as blanks cannot be lowercased anyway, just use
searchString += item[stringFields[field]].toLowerCase() + ' ';
Here is a translated code from babeljs itself, as commented above.
'use strict';
function filterFunction(items, filters) {
var stringFields = arguments.length <= 2 || arguments[2] === undefined ? ['Title', 'Description'] : arguments[2];
var angular = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3];
// Filter by the keys of the filters parameter
var filterKeys = Object.keys(filters);
// Set up a mutable filtered object with items
var filtered = void 0;
// Angular doesn't like deep clones... *sigh*
if (angular) {
filtered = items;
} else {
filtered = _.cloneDeep(items);
}
// For each key in the supplied filters
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
var _loop = function _loop() {
var key = _step.value;
if (key !== 'TextInput') {
filtered = filtered.filter(function (item) {
// Make sure we have something to filter by...
if (filters[key].length !== 0) {
return _.intersection(filters[key], item[key]).length >= 1;
}
return true;
});
}
// If we're at TextInput, handle things differently
else if (key === 'TextInput') {
filtered = filtered.filter(function (item) {
var searchString = "";
// For each field specified in the strings array, build a string to search through
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = stringFields[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var field = _step2.value;
// Handle arrays differently
if (!Array.isArray(item[field])) {
searchString += (item[field] + ' ').toLowerCase();
} else {
searchString += item[field].join(' ').toLowerCase();
}
}
// Return the item if the string matches our input
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
return searchString.indexOf(filters[key].toLowerCase()) !== -1;
});
}
};
for (var _iterator = filterKeys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
_loop();
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return filtered;
}
p.s. Or there is a better way to use babeljs directly without manually converting it.
I have an array like this
var userdata = [
{"id":1,"gender":"M","first":"John","last":"Smith","city":"Seattle, WA","status":"Active"},
{"id":2,"gender":"F","first":"Kelly","last":"Ruth","city":"Dallas, TX","status":"Active"},
{"id":3,"gender":"M","first":"Jeff","last":"Stevenson","city":"Washington, D.C.","status":"Active"},
{"id":4,"gender":"F","first":"Jennifer","last":"Gill","city":"Seattle, WA","status":"Inactive"}
]
I need to filter this array on some conditions. The form of these conditions are like this.
var search_object = {gender:"M",city:"Seattle, WA"}
// Gender = M and city = 'Seattle, WA'
var search_object1 = {gender:"M"}
var search_object2 = {city:"Seattle, WA"}
// This is same as above
var search_array = {status:["Active","Inactive"]}
// Status Active or Inactive
var search_array = [{status:"Active"},{status:"Inactive"}]
// Same as above
var search_object1 = {gender:"F"}
var search_array = [{status:"Active"},{status:"Inactive"}]
//Gender = F and status = Active or Inactive
var search_object = {gender:"F"}
var search_array = [{status:["Active","Inactive"]}]
// same as above
I have tried looping but failed. Please help or suggest or provide some proper links to get help.
The following code covers all the cases you mentioned.
function search(searchObj, data) {
if(searchObj instanceof Array) {
return data.reduce(function(prev, current, index, array) {
return prev.concat(search(current, data));
}, []);
} else {
var results = data.filter(function(el) {
for(var prop in searchObj) {
if(searchObj[prop] instanceof Array) {
if(searchObj[prop].indexOf(el[prop]) == -1) {
return false;
}
} else
if(el[prop] !== searchObj[prop]) {
return false;
}
}
return true;
});
return results;
}
};
search(search_object, userdata);
Here is the working example in JSFiddle.
And here are some links to the functions I've used above:
Array.prototype.reduce()
Array.prototype.concat()
Array.prototype.filter()
Array.prototype.indexOf()
Just what RGraham said in the comments, you can use the filter function on arrays.
var search_object = {gender:"M",city:"Seattle, WA"};
var filtered = userdata.filter(function(obj){
return (obj.gender === search_object && obj.city === search_object.city)
});
filtered[0];//Array with objects that return true;
I have a function in javascript which can write the output to the console but it is unable to return the value..
fetchData: function(dateToFetch){
if (mP.viewMode == 1){
$.each(mealData.DailymPs, function(k, item){
if( item.Date == formatDate(mP.chosenDate) ){
mP.DayPlan.mPDayData = item;
return mP.populateMealDayPlan();
}
})
} else if (mP.viewMode == 2){
// debugger;
$.each(mealData.DailymPs, function(k, item){
if( item.Date == (dateToFetch) ){
mP.DayPlan.mPDayData = item;
console.log(mP.populateMealDayPlan());
var returnObj = mP.populateMealDayPlan();
return returnObj;
}
})
}
}
You should be able to fix it by changing it from:
...
$.each(mealData.DailymPs, function(k, item){
if( item.Date == (dateToFetch) ){
mP.DayPlan.mPDayData = item;
console.log(mP.populateMealDayPlan());
var returnObj = mP.populateMealDayPlan();
return returnObj;
}
})
...
to
...
var returnObj = null;
$.each(mealData.DailymPs, function(k, item){
if( item.Date == (dateToFetch) ){
mP.DayPlan.mPDayData = item;
console.log(mP.populateMealDayPlan());
returnObj = mP.populateMealDayPlan();
return false; // break out of each()
}
})
if(returnObj != null) return returnObj;
...
Note: You'll also need to externalize the return variable in the if condition. I've demonstrated how that can be done for the else condition.
If you want to return something from a $.each loop, assign it to a variable in the outer scope, return false; to break the loop and then return it after the $.each(); call.
Without seeing mP.populateMealDayPlan, my first guess would be that calling the function twice to get the values changes some internal values of mP. In other words if I am right and you comment out the console.log, there should be a return value. You could also do:
var returnObj = mP.populateMealDayPlan();
console.log(returnObj);
rather than calling mP.populateMealDayPlan in the console.log
If this is not the case then I think we would need more context in order to help.
Your return statement returns from the function passed to the each method, not from your fetchData function. The grep function will be useful here:
fetchData: function(dateToFetch) {
var selector = mP.viewMode == 1 ? function(item) { return item.Date == formatDate(mP.chosenDate) } : function (item) { return item.Date == dateToFetch};
var matched = $.grep(mealData.DailymPs, selector);
if (matched.length) {
var item = matched[0];
mP.DayPlan.mPDayData = item;
console.log(mP.populateMealDayPlan());
return mP.populateMealDayPlan();
}
}
I've created a function to iterate through a UL/LI. This works perfectly, my problem is returning the value to another variable. Is this even possible? What's the best method for this? Thanks!
function getMachine(color, qty) {
$("#getMachine li").each(function() {
var thisArray = $(this).text().split("~");
if(thisArray[0] == color&& qty>= parseInt(thisArray[1]) && qty<= parseInt(thisArray[2])) {
return thisArray[3];
}
});
}
var retval = getMachine(color, qty);
I'm not entirely sure of the general purpose of the function, but you could always do this:
function getMachine(color, qty) {
var retval;
$("#getMachine li").each(function() {
var thisArray = $(this).text().split("~");
if(thisArray[0] == color&& qty>= parseInt(thisArray[1]) && qty<= parseInt(thisArray[2])) {
retval = thisArray[3];
return false;
}
});
return retval;
}
var retval = getMachine(color, qty);
The return statement you have is stuck in the inner function, so it won't return from the outer function. You just need a little more code:
function getMachine(color, qty) {
var returnValue = null;
$("#getMachine li").each(function() {
var thisArray = $(this).text().split("~");
if(thisArray[0] == color&& qty>= parseInt(thisArray[1]) && qty<= parseInt(thisArray[2])) {
returnValue = thisArray[3];
return false; // this breaks out of the each
}
});
return returnValue;
}
var retval = getMachine(color, qty);