initialized without binding with angular - angularjs

I need to initialized without binding.
I've tried the following. But I did not succeed
$scope.emptyRow = $scope.newsCategories[1];
$scope.newsCategories[1].Name = "yes";
$scope.emptyRow.Name = "test";
alert($scope.emptyRow.Name); // alert => test
alert($scope.newsCategories[1].Name);// alert => test
I need this :
$scope.emptyRow = $scope.newsCategories[1];
$scope.newsCategories[1].Name = "yes";
$scope.emptyRow.Name = "test";
alert($scope.emptyRow.Name); // alert => test
alert($scope.newsCategories[1].Name);// alert => yes
How to do this?

This has nothing to do with binding, but rather basic javascript.
The line: $scope.emptyRow = $scope.newsCategories[1];
is explicitly saying that you want $scope.emptyRow and $scope.newsCategories[1] to be pointing to the exact same object. Hence, when you change a child value of either (like Name), it will effect the other.
It looks like you want to be able to copy the object in question. For that you can use angular.copy(). An example use in your case would be:
$scope.emptyRow = angular.copy($scope.newsCategories[1]);
Read here for more info.

Related

concat strings to Reference react fc prop by constructed name from inside the component

I have a series of commonly named properties, and I'd like to have the un-common part of the name used in other places. I know that wording is a little convoluted, but perhaps an example will help. What I want is something like:
const MyComponent = ({lgProp, xlProp, mdProp, smProp, defaultProp}) => {
let current = defaultProp;
let myString = 'foo';
['sm', 'md', 'lg', 'xl'].forEach(size => {
const newValue = // somehow get the value of the property ${size}Prop
if (current !== newValue) {
myString += ` ${size}: ${newValue}`;
current = newValue;
}
});
}
The canonical answer to this type of question seems to be here, but all of the answers there either refer to dynamically referencing keys in objects, or dynamically referencing variables in pure JS in the Window or this scope. I can't seem to make any of them work for referencing property names.
There are also several sections on dynamically creating property names for components, but that's the wrong direction for me.
Things I've tried:
newValue = `${size}Prop`; // string
newValue = [`${size}Prop`]; // string
newValue = [${size} + 'Prop']; // string
newValue = this[${size} + 'Prop'] // TypeError
I mean, there are only so many props, so I could just write a bunch of if statements, but that seems so inelegant. Is there an attractive/elegant way to variably reference the prop names?

Should be an array, but typeof says it's an object, Chrome console displays it as an array

I have this problem which may sounds stupid but I don't really understand the whys.
I declare it as a variable: let [ randomQuoterState, setrandomQuoterState ] = useState([]); Then pass it into a component inside the return: <UserOutput set={setrandomQuoterState} current={randomQuoterState} number={1}/>
The following code is inside the component:
let toSet = [];
toSet[props.number] = quoteArray[Math.floor(Math.random() * quoteArray.length)];
let quote = props.current;
if (quote[props.number]){
delete quote[props.number];
console.log("deleted")
}else {
console.log("this does not exist");
}
console.log(typeof(toSet[props.number]));
console.log(toSet[props.number].lenght)
console.log(toSet[props.number]);
quote[props.number] = toSet[props.number][Math.floor(Math.random() * toSet[props.number].lenght)];
props.set(quote);
The Consol displays it as an array, but the typeof function says its an object, and it doesn't have a length property.
I would appreciate any help or explanation, I thought about it a lot, but I couldn't come up with anything.
Arrays are objects in Javascript. In fact, there is no array type.
To see if it is an array, you should try console.log((toSet[props.number]).constructor.name) and do your checks against toSet[props.number] instanceof Array.
Do not use (toSet[props.number]).constructor.name == 'Array' in your comparisons, because you could have something that has inherited from Array but whose constructor name is different.
In JavaScript both object and array are of type Object.
In case you want to determine exact type, you can use constructor property.
const data = {};
data.contructor.name === 'Object'; // Returns True
const data = [];
data.contructor.name === 'Object'; // Returns True
data.contructor.name === 'Object'; // Returns False
Above can used to determine String, Date etc as well.
Alternatively you can use libraries like lodash which has function for these things.
However that is overkill I guess.
Hope it helps.

How do I get the text from the li tag

How do I get the text from the li tag? I want to find the text "Password is required." only, not the text inside strong tag.
<li><strong>Error:</strong> Password is required.</li>
You need to show your code for somebody to give a complete answer. I guess that you already know how to do something like the following
WebElement something = driver.FindElement(By.CssSelector(?))
string s = something.Text;
The next bit seems to be where you are stuck. There you need to parse the string s. That is nothing to do with Selenium-Webdriver. You could do something like
string[] s2 = s.split(new string[] {">","<"});
were the last element in s2 would be your answer here. This would be totally non generic though. Is this a situation in which you always want to purge html?
Here is the method developed in python.
def get_text_exclude_children(element):
return driver.execute_script(
"""
var parent = arguments[0];
var child = parent.firstChild;
var textValue = "";
while(child) {
if (child.nodeType === Node.TEXT_NODE)
textValue += child.textContent;
child = child.nextSibling;
}
return textValue;""",
element).strip()
How to use in this:
liElement = driver.find_element_by_xpath("//li")
liOnlyText = get_text_exclude_children(liElement)
print(liOnlyText)
Please use your possible strategy to get the element, this method need an element from which you need the text (without children text).

AngularJS Filter expression replacing with variable instead

I have a table object and I want to filter out a particular "index" row using filter function as shown below.
However, $controller.expression is not working out.
IF `$controller.expression = "3";
It would work. But not
$controller.expression = "3,4";
$controller.expression = [3,4];
$scope.dataToBeTransfer = $scope.myDataTable.filter(function (el)
{
return el.index== $controller.expression;
});
So how do I solve this issue?
If you're going to use an array you need to loop through to see if el.index is included in the array. This is probably the easiest way to do it from the given code:
$scope.dataToBeTransfer = $scope.myDataTable.filter(function (el) {
return $controller.expression.includes(el.index);
});

rootScope is upating on scope variable update

I have created a rootScope variable like
$rootScope.globalData = data;
$rootScope.globalData.chillerConditions.HeatSource.Value = "ST"; //Default Value
$scope.chillerConditions.HeatSource.Value = 1; //Default Value
where data is my returning value from api. Also create a scope variable which is a object contains a list of items.
$scope.chillerAttributes = data.ObjCandidateListChillerAttributes;
$scope.chillerConditions = data.ObjCandidateListConditions;
On HTML I have:
<select ng-model="chillerConditions.HeatSource.Value" style="width:53%;" ng-options="item.Id as item.Description for item in ValidRatingHeatSource" ng-change="heatSourceChanged()" id="ddRatingHeatSource" class="form-control search-select designComboboxHeight" data-container="body"></select>
Here ValidRatingHeatSource is
$scope.ValidRatingHeatSource = \*list of items*\
On change of Drop Down I have written an function. In that
if($scope.chillerConditions.HeatSource.Value == 2)
{
$rootScope.globalData.chillerConditions.HeatSource.Value = "HW";
}
else
{
$rootScope.globalData.chillerConditions.HeatSource.Value = "ST";
}
Till now was the my current code.
Issue is :
When the above function is called then whenever current $rootScope varible i.e. $rootScope.globalData.chillerConditions.HeatSource.Value is changed to "HW" or "ST" it also changing $scope.chillerConditions.HeatSource.Value to "HW" or "ST".
Why so?
Is there any inbuilt functionality in angularjs?
Please suggest if I am making any mistake? New suggestion are also welcome.
This behavior is the way JavaScript works and has nothing to do with AngularJS. JavaScript is an object-oriented (prototype-based) language where objects are addressed by reference and not by value. E.g. assign car2 to car1 and both of them will reference the same object (JSFiddle)
var car1 = {make: "Audi"}
var car2 = car1;
car2.make = "Toyota";
So in your case, $rootScope.globalData.chillerConditions.HeatSource and $scope.chillerConditions.HeatSource are the same object.
Rather, it seems like you want to create a copy. You can do so with angular.Copy
$scope.chillerAttributes = angular.copy(data.ObjCandidateListChillerAttributes);
$scope.chillerConditions = angular.copy(data.ObjCandidateListConditions);
In your example u have both ng-model and ng-change, so:
1. User change value in select.
2. $scope.chillerConditions.HeatSource.Value changes (ng-model)
3. heatSourceChanged starts (ng-change) -> $rootScope.globalData.chillerConditions.HeatSource.Value changes
So everything works as should...

Resources