So I will do something like this often
save(...keys: string[]) {
keys.foreach(x => // save);
}
I can call this any of these ways because of the spread operator.
save('string1', 'string2');
save(['string1', 'string2']);
save('string');
I love this behavior but what I have a case where I have an #input on a component that I want to behave the same way. sometimes I want to just give it one item, other times I want to give it an array. How could this syntax be applied?
I want to be able to do something like this.
#Input() ...myClass: ClassBase[] = [];
And usages like this.
// ts
currentClass = new ClassBase();
conflictingClasses = [new ClassBase(), new ClassBase()];
// html
<my-component [myClass]="currentClass"></my-component>
<my-component [myClass]="conflictingClasses"></my-component>
How can I get this kind of behavior? We already use this component in several places but we only give it one item, I would like to not have to mass refactor to change this component to take an array of items.
thanks!
I can call this any of these ways because of the spread operator.
No, the premise of your question is wrong. You must call it with n number of string arguments. A string array string[] is not the same thing. This is shown below:
function save(...keys: string[]) {
keys.forEach(x => /** save */);
}
save('string1', 'string2'); // OKAY
save('string'); // OKAY
save(['string1', 'string2']); // ERROR !
Please as a different question instead of editing this as it will probably not get much attention after edits 🌹. PS: have fun and stay happy!
Related
I am new to React JS & currently trying to iterate a certain data to present the same in react js but not able to do the same. The data which looks something like this
Now, the final output should be look something like this in tabular format
The things which I tried are:-
The error which I am getting below one is for 1 image and for second, the code is not getting parsed.
[![error][5]][5]
So, how to achieve the desired output in react js
It looks like you're trying to use map onto an object, while you should use it on a collection. Maybe try something like this :
Object.values(listData.data).map((meetingRoom) => { // your code here });
This will allow you to use the content inside your data object as an array of objects.
Edit : Sorry, I didn't understand you need to access the key as well as the value. To achieve that you can simply use Object.entries which will return the key (Meeting Room 1, Meeting Room 2 in this instance) in the first variable and the array of items in the second variable.
Here's a quick example:
Object.entries(listData.data).forEach(([key, value]) => {
console.log(key, value);
// You could use value.map() to iterate over each object in your meeting room field array.
});
Note : you can also use a for (... of ...) loop like this instead of a forEach :
for (const [key, value] of Object.entries(listData.data)) {
console.log(key, value);
};
For more information about the Object.entries method, feel free to check the MDN Webdocs page about it here.
I have some code that includes a react form that has something like this in it :
<input id="region"></input>
I have a function that is called from a button click and I want to get the value of the id "region".
I have seen that supposedly I can do something like this :
let test : string = <HTMLInputElement>document.getElementById(region).value;
But I can verify 8 ways to Sunday that does not work. I get syntax errors saying a comma is missing if I try that.
So is there a way to do this? What am I missing? treat me like an idiot since I am only 48 hours into typescript.
I assume you're using React due to the tag, and thus I assume the following code is in a tsx file.
let test : string = <HTMLInputElement>document.getElementById(region).value;
You cannot use arrow bracket casts in TSX files because TypeScript will assume you're trying to use a React Element. You must instead use the as form of casts:
let test : string = (document.getElementById(region) as HTMLInputElement).value;
I would like to add a couple of notes, because I cannot comment. While using TypeScript, and although all valid JS is valid TS as well, #Heretic Monkey is right the DOM is not generally used to manipulate the values.
Additionally, there are two mistakes in your TypeScript:
---let test : string = <HTMLInputElement>document.getElementById(region).value;---
Firstly, I believe you cannot initialize your variable and access the element's value at the same time. You ought to first assign your variable to the input element, and then use the variable to access its value. Example:
let test : string = <HTMLInputElement>document.getElementById(region);
console.log(test.value);
Secondly, the element's id should be quoted in both cases. When assigning the id inside the tag itself, and when trying to access it.
let test : string = <HTMLInputElement>document.getElementById("region");
A little late to this question, but if it is not solved and you're still struggling, give it a go. Hope it helps.
Typescript is a superset of Javascript. Every valid Javascript code is a valid Typescript code.
If what you are trying to do isn't working as intended, it is for another reason.
you must use ref in react:
Then call it in your function.
Like this
private regioninput: HTMLInputElement;
constructor(props) {
super(props);
this.regioninput = null;
this.setregionInputRef = element => {
this.stepInput = element;
};
}
your element change :
<input type="text" ref={this.setregionInputRef} />
I am using angular-meteor and would like to perform a function on each object. I tried running this function within an ng-repeat in the view, but I am getting massive amounts of function calls and can't figure out why. I tried to make it as simple as possible to demonstrate what is going on.
constructor($scope, $reactive) {
'ngInject';
$reactive(this).attach($scope);
this.loaderCount = 0;
this.helpers({
loaders() {
return Loaders.find( {isloader:true}, {sort: { name : 1 } })
}
});
That gives me 26 Loaders. My function just adds 1 to the count every time the function is called:
displayLoaderCount()
{
return ++this.loaderCount;
}
Now in my view, I am looping through each loader, and calling the function. This should in my mind give me 26, but instead I am getting 3836.
<tr ng-repeat="loader in loaderExhaustion.loaders">
<td>{{loaderExhaustion.displayLoaderCount()}}</td>
Can anyone help explain this to me? Ideally I would like to loop over the contents in my module but as the collection is async, when the loop starts the length of the collection is 0, hence why I made the call in the view.
THANKS!
Every time angular enters a change detection cycle, it evaluates loaderExhaustion.displayLoaderCount(), to know if the result of this expression has changed, and update the DOM if it has. This function changes the state of the controller (since it increments this.loaderCount), which thus triggers an additional change detection loop, which reevaluates the expression, which changes the state of the controller, etc. etc.
You MAY NOT change the state in an expression like that. For a given state, angular should be able to call this function twice, and get the same result twice. Expressions like these must NOT have side effects.
I can't understand what you want to achieve by doing so, so it's hard to tell what you should do instead.
I'm attempting to learn backbone.js and (by extension) underscore.js, and I'm having some difficulty understanding some of the conventions. While writing a simpel search filter, I thought that something like below would work:
var search_string = new RegExp(query, "i");
var results = _.filter(this, function(data){
return search_string.test(data.get("title"));
}));
But, in fact, for this to work I need to change my filter function to the following:
var search_string = new RegExp(query, "i");
var results = _(this.filter(function(data){
return search_string.test(data.get("title"));
}));
Basically, I want to understand why the second example works, while the first doesn't. Based on the documentation (http://documentcloud.github.com/underscore/#filter) I thought that the former would have worked. Or maybe this just reflects some old jQuery habits of mine... Can anyone explain this for me?
I'd guess that you're using a browser with a native Array#filter implementation. Try these in your console and see what happens:
[].filter.call({ a: 'b' }, function(x) { console.log(x) });
[].filter.call([1, 2], function(x) { console.log(x) });
The first one won't do anything, the second will produce 1 and 2 as output (http://jsfiddle.net/ambiguous/tkRQ3/). The problem isn't that data is empty, the problem is that the native Array#filter doesn't know what to do when applied to non-Array object.
All of Underscore's methods (including filter) use the native implementations if available:
Delegates to the native filter method, if it exists.
So the Array-ish Underscore methods generally won't work as _.m(collection, ...) unless you're using a browser that doesn't provide native implementations.
A Backbone collection is a wrapper for an array of models, the models array is in c.models so you'd want to:
_.filter(this.models, function(data) { ... });
Backbone collections have several Underscore methods mixed in:
Backbone proxies to Underscore.js to provide 28 iteration functions on Backbone.Collection.
and one of those is filter. These proxies apply the Underscore method to the collection's model array so c.filter(...) is the same as _.filter(c.models, ...).
This mixing-in is probably what's confusing the "should I use the native method" checks that Underscore is doing:
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
You can use _.filter on a plain old object (_.filter({a:'b'}, ...)) and get sensible results but it fails when you _.filter(backbone_collection, ...) because collections already have Underscore methods.
Here's a simple demo to hopefully clarify things: http://jsfiddle.net/ambiguous/FHd3Y/1/
For the same reason that $('#element') works and $#element doesn't. _ is the global variable for the underscore object just like $ is the global variable for the jQuery object.
_() says look in the _ object. _filter says look for a method named _filter.
I'm looking for an equivalent method to select a class element like this $(".className") in Jquery for ExtJS.
I understand that Ext.get() only takes in an id. Your help will be very much appreciated.
Cheers,
Mickey
Edited:
Let me explain further. I want to be able to do something like Ext.get after I did a "select". For example:
$(".className").css("width");
I understand that Ext.Element has getWidth() method. I was hoping I can do something like...
Ext.select(".className").getWidth(); // it just return me [Object object]
Maybe i don't understand it well.
Thanks a mil.
Yes, Ext.select() is what you want. It returns a CompositeElement (same API as a single Element, but contains an internal collection of all selected elements). You could do this to see the widths of each element:
Ext.select('.className').each(function(el){
console.log(el.getWidth());
});
The way you called it is more useful for operating on the elements in some way, e.g.:
Ext.select('.className').setWidth(100);
I think you are looking for:
Ext.query(".className");
This method allows you to get elements by the given query string like jQuery does.
EDIT
var els=Ext.query(".className"), ret=[];
for(var i=0; i<els.length; i++)
{
ret.push(els[i].getWidth());
}
If you want the component you can use this:
Ext4 and up.
Ext.ComponentQuery.query('panel[cls=myCls]');
And you will get and array of this components
source: http://docs.sencha.com/ext-js/4-1/#!/api/Ext.ComponentQuery