Target Variable from Variable Value - javascript

I am trying to target a variable from a variable value that has been passed in from function arguments. I don't know how to do this. P.S. the variables at the top are also used by other functions
let cardvalue0 = false;
let cardvalue1 = false;
function myfunction (card) {
if (card === false) {
card = true;
//ether cardValue 0 or 1 should now be true
return card;
}
}
// exturnal html
<button onclick="myfunction("cardValue0")"></button>
<button onclick="myfunction("cardValue1")"></button>
new try by me
//define cards
let card0State = false;
let card1State = false;
//toggle card status (read or not)
function cardToggle(card) {
console.log(card);
card = !card
console.log(card);
return card;
}
// external html
<button onclick="myfunction(cardValue0)"></button>
<button onclick="myfunction(cardValue1)"></button>

target a variable from a variable value? If I understood you right you want to access a variable cardvalue0 inside the function myfunction.
You can access it using, eval(card) but definitely not advised to do
function myfunction (card) {
if (eval(card) === false) { //this will work
card = true; //however you cannot change the original value
return card;
}
}
You can get this by using objects
let cardDict = { "cardvalue0" : false,
"cardvalue1" : false}
function myfunction (card) {
if (cardDict[card] === false) {
cardDict[card] = true;
return cardDict[card];
}
}

Would it be possible to store card0State and card1State in an object instead? Then you could reference them as keys to the object instead.
const cardvalues = {};
cardvalues.cardvalue0 = false;
cardvalues.cardvalue1 = false;
function myfunction (cardNumber) {
if (cardvalues[cardNumber] === false) {
cardvalues[cardNumber] = true;
//ether cardValue 0 or 1 should now be true
return cardvalues[cardNumber];
}
}
// exturnal html
<button onclick="myfunction('cardvalue0')"></button>
<button onclick="myfunction('cardvalue1')"></button>
Then you aren't declaring a new variable in the function scope and you are directly altering the key values on the object. This is usually better than a variable variable pattern.
"Variable" variables in Javascript?

the simpler would be moving the original variable (cardvalue0 and cardvalue1) in a Map or an object, so you could have :
cards = {
cardvalue0 : false,
cardvalue1 : false
}
function foo(cardName) {
cards[cardName] = !cards[cardName];
return cards[cardName]
}
}
if you can not move cardvalue0 and cardvalue1, you could simply hardcode them, but it will become ugly really fast.
function foo(cardName) {
if(cardName === "cardvalue0") {
cardValue0 = !cardValue0;
return cardValue0;
} else if(cardName === "cardvalue1")
cardValue1 = !cardValue1;
return !cardValue1;
}
eval would be the only way to get a variable from a string representation, but is not a good idea.

Related

make variable available in other function

I have a function
function formSubmitListener() {
$(".js-form").submit(event => {
event.preventDefault();
let input = fetchInput();
validateInput(input);
if (isValid) {
serverCall()
}
});
}
validateInput returns a isValid boolean of true (if all fields on a form have been filled out) that I need to make available for the if statement. If at all possible I want to prevent the use of a global variable.
How do I make the boolean available ?
function formSubmitListener() {
$(".js-form").submit(event => {
event.preventDefault();
let input = fetchInput();
let isValid = validateInput(input);
if (isValid == true) {
serverCall()
}
});
}
this might be what you want. set the validateInput(input) function call to a variable and use that variable since it will store the true/false.
or another way by putting the direct function in the if where it checks whats returned
function formSubmitListener() {
$(".js-form").submit(event => {
event.preventDefault();
let input = fetchInput();
if (validateInput(input)) {
serverCall()
}
});
}

Trying to check if object exists in Knockout Observable Array

I'm trying to check if an object has the same observable values of other objects with the same observable properties inside an observable array.
I created a foreach loop which evaluates if any of the observables match. The problem I'm having is that condition always evaluates to true, even though these values are different. I'm using typescript and knockout.
Here's the code :
export function addPDFToPackage(heat: MTRHeat): void {
var koHeat: MTRHeatWithInclude = ko.mapping.fromJS(heat);
koHeat.Include = ko.observable(true);
var arrayOfHeats = model.mtrPackage.Heats();
var addToHeats = () => model.mtrPackage.Heats.push(koHeat);
var duplicate = false;
arrayOfHeats.forEach(function (koHeat, i) {
if (arrayOfHeats[i].MTRID() == koHeat.MTRID() && arrayOfHeats[i].HeatID() == koHeat.HeatID() && arrayOfHeats[i].PartID() == koHeat.PartID()) {
duplicate = true;
}
else
duplicate = false;
})
if (!!model.mtrPackage.PackageID()) {
if (duplicate) {
var c = confirm("Warning: Duplicate MTR located on current package.Proceed ?")
if (c) {
ServiceMethods.addHeatToPackage(model.mtrPackage.PackageID(), heat.HeatID).done(addToHeats);
}
if (!c) {
return;
}
}
}
}
First problem: Your loop compares each object to itself because you re-use the variable name koHeat. I believe you really wanted to refer to the "outer" koHeat.
Second problem: You overwrite the duplicate variable in every loop iteration. This is probably not what you intend. Instead you want to stop the loop as soon as a duplicate is found.
How about something along those lines?
export function addPDFToPackage(heat: MTRHeat): void {
var koHeat: MTRHeatWithInclude = ko.mapping.fromJS(heat);
var packageId = model.mtrPackage.PackageID();
koHeat.Include = ko.observable(true);
function equals(a: MTRHeatWithInclude, b: MTRHeatWithInclude): boolean {
return a.MTRID() == b.MTRID() && a.HeatID() == b.HeatID() && a.PartID() == b.PartID();
}
if ( !!packageId && (
!model.mtrPackage.Heats().some(item => equals(item, koHeat)) ||
confirm("Warning: Duplicate MTR located on current package.Proceed ?")
)
) {
ServiceMethods.addHeatToPackage(packageId, heat.HeatID).done(() => {
model.mtrPackage.Heats.push(koHeat);
});
}
}
The equals() function should ideally be a method of the MTRHeatWithInclude class.
I think you're getting a clash between koHeat defined here:
var koHeat: MTRHeatWithInclude = ko.mapping.fromJS(heat);
koHeat.Include = ko.observable(true);
And the variable defined within the forEach call. It's always returning true as (within the scope of the forEach) arrayOfHeats[i] === koHeat.
Try this:
export function addPDFToPackage(heat: MTRHeat): void {
var koHeat: MTRHeatWithInclude = ko.mapping.fromJS(heat);
koHeat.Include = ko.observable(true);
var arrayOfHeats = model.mtrPackage.Heats();
var addToHeats = () => model.mtrPackage.Heats.push(koHeat);
var duplicate = false;
arrayOfHeats.forEach(function (koHeat2, i) {
if (koHeat2.MTRID() == koHeat.MTRID() &&
koHeat2.HeatID() == koHeat.HeatID() &&
koHeat2.PartID() == koHeat.PartID()) {
duplicate = true;
}
})
if (!!model.mtrPackage.PackageID()) {
if (duplicate) {
var c = confirm("Warning: Duplicate MTR located on current package.Proceed ?")
if (c) {
ServiceMethods.addHeatToPackage(model.mtrPackage.PackageID(), heat.HeatID).done(addToHeats);
} else {
return;
}
}
}
}

Pass property with dot notation(sometimes) to function

I've got a function that is looking through a specified collection and highlighting the checkboxes for the items that are present in that collection.
function highlightFiltersPresentInTransactions(collection, collectionproperty, child) {
var found = false;
angular.forEach(collection, function (filterType) {
if (scope.vm.transactions) {
found = scope.vm.transactions.filter(function (obj) {
if (child) {
return obj[collectionproperty][child] === filterType.name;
} else {
return obj[collectionproperty] === filterType.name;
}
});
}
if (found) {
filterType['has-transaction'] = (found.length > 0);
}
});
}
I'm able to call it and it correctly works like this
highlightFiltersPresentInTransactions(scope.filterTypes, 'target', 'type');
highlightFiltersPresentInTransactions(scope.actionTypes, 'transactionType');
What I would like to be able to avoid is the check whether there is a child element that needs to be checked.
I attempted to call the function as such:
highlightFiltersPresentInTransactions(scope.filterTypes, 'target.type');
Since this is a string it doesn't find the property. I also tried creating a blank target object then passing target.type without the quotes.
How can I dynamically pass in a property that might or might not have a child property to my function?
How about passing a function reference to the function?
highlightFiltersPresentInTransactions(scope.filterTypes, function(o) { return o.target.type; });
highlightFiltersPresentInTransactions(scope.filterTypes, function(o) { return o.transactionType; });
This can be implemented pretty easily:
function highlightFiltersPresentInTransactions(collection, readFn) {
var found = false;
angular.forEach(collection, function (filterType) {
if (scope.vm.transactions) {
found = scope.vm.transactions.filter(function (obj) {
return readFn(obj) === filterType.name;
});
}
if (found) {
filterType['has-transaction'] = (found.length > 0);
}
});
}
If you don't want to do that, one way or another you'll have to split your string target.type into separate properties, and do it your existing way (just without the explicit parameter for child).

AngularJS setting up a function to prevent duplication

At the moment I have duplicate code where I have the following examples:
if ($scope.user.window.title == 'true'){
if (this.title){
title = '<h2>'+this.title+'<h2>';
} else {
title = '';
}
} else {
title = '';
}
if ($scope.user.window.football == 'true'){
if (this.football){
football = '<p>'+this.football+'<p>';
} else {
football = '';
}
} else {
football = '';
}
I have tried the following but it doesn't work, it says that the $scope.user.window.football and $scope.user.window.title don't exist. I think it is down to the below function sending the value through as a string for my $scope.
function CheckWindow(element,tag) {
console.log(element);
if ($scope.user.window.element == 'true'){
if (this.element){
element = '<'+tag+'>'+this.element+'</'+tag+'>';
} else {
element = '';
}
} else {
element = '';
}
}
Usage
CheckWindow('title','h2')
CheckWindow('football','p')
$scope.user.window.element tries to access the property named element of $scope.user.window. You need $scope.user.window[element] instead.
this refers to the created function's scope. You could pass a new argument that for example.
that.element will have to be rewritten to that[element], for the same reason as in #1.
You can't assign a new value to a function's parameter (well, you can, but it won't be accessible outside the function's scope). Better return the value.
So:
function CheckWindow(that, element, tag) {
if ($scope.user.window[element] && that[element]){
return '<'+tag+'>'+that[element]+'</'+tag+'>';
}
return '';
}
title = CheckWindow(this, 'title', 'h2');
football = CheckWindow(this, 'football', 'p');
try
$scope.user.window[element]
When you need to reference a property as a sttring, you must use bracket notation.
Also, I doubt that 'this' will reference what you want. You may need to angular.bind this to the method.

How can I assign value returned from anon function?

Is it possible to avoid declaring global variable and instead assign it the result of the anonymous function?
var logged = false;
Ext.each(userRecords, function (userRecord) {
if (userRecord.get('id') == currentuser) {
if (userRecord.get('password') == currentuserpassword) {
logged = true;
}
}
});
Example:
var logged = Ext.each(userRecords, function (userRecord) {
if (userRecord.get('id') == currentuser) {
if (userRecord.get('password') == currentuserpassword) {
return true;
}
}
});
If you're using Ext JS 4.0 or later, just replace your Ext.each in the second code block with Ext.Array.some and your code will work as is.
Executes the specified function for each array element until the function returns a truthy value. If such an item is found, the function will return true immediately. Otherwise, it will return false.
Using ECMAScript 5 some array method:
var logged = userRecords.some(function (userRecord) {
if (userRecord.get('id') == currentuser) {
if (userRecord.get('password') == currentuserpassword) {
return true;
}
}
return false;
});

Categories

Resources