I've recently taken upon myself to add setter and getter methods to my class.
Since doing this, many parts of my code got broken and I'm unable to access getter methods.
Take the example below:
private loadInputs() : Input[] {
var inputs = <Input[]>this.get('inputs');
inputs.sort((a,b) => a.QuoteRef().localeCompare(b.QuoteRef()))
return( inputs || [] );
}
My input class has 2 variables,
_Project: string
_line: string
Which I access using a method QuoteRef()
public QuoteRef(): string {
return this._Project.concat('-' + this._Line.toString().padStart(3,'0'));
}
Whenever I try to access a method or a getter from my class on an item that is casted as an Input, I can see the variables (though not access them as they are private), but the prototype section doesn't contain any of the methods.
This triggers the following error in the website console:
TypeError: a.QuoteRef is not a function
What am I doing wrong?
Update
I got it to work by updating the code as follows:
inputs.sort((a,b) => {
let first = new Input(a);
let second = new Input(b);
return first.QuoteRef().localeCompare(second.QuoteRef());
});
Without seeing your complete class I can only guess, but I think that a and b in your sort are not of the type you expect. I can't see what this.get('inputs') does, but I suspect it is not returning an array with Input class objects. Hence the function cannot be found (is not a function). You could try:
inputs.sort((a,b) => {
console.log(typeof a);
console.log(typeof b);
a.QuoteRef().localeCompare(b.QuoteRef());
})
and check what the type is. Then check what your this.get actually returns.
Edit: forgot to mention that your IDE probably does not warn you because you cast the output of this.get to <Input[]>.
Related
I am trying to understand the value of this at different points in a script. Questions similar to mine have been answered in this forum but those answers are considerably above my current learning level.
In my code experiments, I am using console.logs to return the this value. The value returned is always as expected, but the format of the returned value is inconsistent, which leads me to wonder why.
This code returns the expected Window object for the first 3 log commands to be executed but returns only the object literal for the 4th command, executed from the object's method.
var myName = {
name: "James",
sayName: function() {
console.log(this, 4);
console.log(this.name)
}
}
console.log(this, 1);
function myFunction() {
console.log(this, 2);
function nestFunction() {
console.log(this, 3);
myName.sayName();
}
nestFunction();
}
myFunction();
I have 3 questions: Why doesn't console.log return the name of the object? Is there a way to make it do so? Is there a simple way to do that other than console.log? Any help would be appreciated.
Ok I was going through your code to see what you specifically mean
here is the short explanation as to why THIS is different in some of the places
This keyword refers to the object it belongs to. Generally you used it to refer to the global window object .That's what is reflecting in your console log 1,2,3 .
Calling this in static javaScript object will return the javaScript object ,not the window object that is what is reflecting in the console.log(this,4).
So it gives you a way to call elements inside a static object .
Another way to understand this keyword is to look at constructors .The best example of the keyword
this
is inside a constructor function
var myObj = function(){
function myObj(ref)
{
this.name = "";
this.Item = "";
this.ref = ref;
this.speak();
}
myObj.prototype.speak =function()
{
this.name = 'James';
this.item = 'cheese';
console.log(this.ref)
//and the constuctor object
console.log(this)
}
return myObj;
}();
var e = new myObj('a Refrence string');
This should give you a basic understanding of how this works
here is more info to get you started Wschools.com
I have a computed array which is full of tags and updates depending on what selection i make in the select box. I would like to take this array and pass it to a method and then run a method to update what “results” have an active class. Although I get an array saying I can’t run forEach on this element.
Been through a few topics and understand computed properties dont work like that but surely there is a way around this.
https://jsfiddle.net/39jb3fzw/6/
Short Snippet
methods: {
updateOutput() {
var tags = this.tagArray;
tags.forEach(function(tag) {
console.log(tag);
})
}
},
computed: {
concatenated: function () {
var ret = this.selected.concat(this.selected2, this.selected3);
this.tagArray = ret;
//this.updateOutput();
return ret;
}
}
Full Output
https://jsfiddle.net/39jb3fzw/6/
Thanks again :slight_smile:
It looks like the issue is the line:
var ret = this.selected.concat(this.selected2, this.selected3);
That line of code is returning an empty string rather than an array. This is because this.selectedX is a string rather than an Array. This explains why tag.forEach is undefined. forEach doesn't exist on the String prototype.
You can create this an array instead be doing
var ret = [ this.selected, this.selected2, this.selected3 ]
From there you can set this.tagArray to ret
Hope this helps
Suppose the following code:
TestComponent.propTypes = {
text: React.PropTypes.string,
myEnum: React.PropTypes.oneOf(['News', 'Photos'])
};
I did the following in another file (that was using TestComponent):
if (TestComponent.propTypes.text === React.PropTypes.string) {...}
if (TestComponent.propTypes.myEnum === React.PropTypes.oneOf) {...}
Well, to my satisfaction the first if worked. But the second if never returned true. I tried to modify it to the syntax below, but it did not help.
if (TestComponent.propTypes.myEnum === React.PropTypes.oneOf(['News', 'Photos'])) {...}
So, the question is: What mechanism is there to discover the type of a prop?
I know that React tests the value of a prop against the propType to validate it. However, I need access to the 'expected type' as well to do my stuff.
BTW, here's an excerpt from the React code that validates propTypes (shortened for the sake of brevity):
function createPrimitiveTypeChecker(expectedType) {
function validate(props, propName, componentName, location, propFullName){
var propValue = props[propName];
var propType = getPropType(propValue);
if (propType !== expectedType) {
// return some Error
}
return null;
}
return createChainableTypeChecker(validate);
}
As you can see the parameter of the outer function is expectedType. It is used in the inner validate function (if (propType !== expectedType)). However, React does not save the expectedType into a member variable so that it can be accessed by outside code. So how does outside code figure out the type of the propType??
My point is not to 'validate' a specific value for the prop. That gets taken care of by React very well. My point is to do some specific logic depending on the prop type, which I can't get to with types like anyOf, objectOf, shape, etc.
Any thoughts, suggestions??
Short answer, you can't compare these, because they point to different functions. When you call oneOf, it returns another function.
Explanation: The problem here is that React.PropTypes.oneOf is the function createEnumTypeChecker.
Whereas React.PropTypes.myEnum will contain the return value of calling the oneOf function - because in the propTypes definition you have to actually call oneOf().
The result of calling oneOf() is a different function, declared inside createChainableTypeChecker().
Unfortunately, your second try, won't work either because these functions are different, they're created each time you call oneOf(). See createChainableTypeChecker in ReactPropTypes.js
var chainedCheckType = checkType.bind(null, false);
chainedCheckType.isRequired = checkType.bind(null, true);
return chainedCheckType;
Solution: I propose you test the names of the functions. This will prove that this is a valid React Prop type.
// returns false
React.PropTypes.oneOf(['myArr']) === React.PropTypes.oneOf(['myArr'])
// returns true
React.PropTypes.oneOf(['myArr']).name == React.PropTypes.oneOf(['myArr']).name
// this should return true in your case:
if ( TestComponent.propTypes.myEnum.name === React.PropTypes.oneOf().name )
Unfortunately, all non-primitive React propTypes use createChainableTypeChecker, and this always returns a function with the name checkType. If this name would be different for each propType, then you would be able to check which type is used. As it is now, you can't know if it's oneOf, objectOf or any of the others, including any.
I am trying to implement something like a HTMLCollection which is an array that can lose/gain elements without JS action.
duk_push_object(ctx);
duk_push_string(ctx, "length");
duk_push_c_function(ctx, my_length_getter, 1);
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER);
duk_push_c_function(ctx, my_item_getter, 1);
duk_put_prop_string(ctx, -2, "item");
Doing it like above I get an object on which I can read the my_array.length property and get an item by calling method my_array.item(index). But I don't get an item by using my_array[index].
If I replace the first line above by
duk_push_array(ctx);
I get an error that the length property is not configurable.
Is it possible to achieve what I want? An array with 'lazy' element binding? I have the impression that NetSurf somehow manages to do this but haven't quite worked out how ...
Ecmascript provides two main standard mechanisms for property virtualization: getters/setters (accessors) and the Proxy object. Getters/setters are limited to properties you explicitly set up beforehand so they don't always work for fully virtualizing an object, but a Proxy object can capture among other things all property reads and writes.
You should be able to implement your use case using a Proxy. Duktape implements a subset of the Proxy traps (documented in http://duktape.org/guide.html#es6-proxy). As a minimal example of capturing all property reads and writes (but forwarding them to the target):
var target = { foo: 'hello' };
var proxy = new Proxy(target, {
get: function (targ, key) {
print('get', key);
// may also return a virtualized value
return targ[key];
},
set: function (targ, key, val) {
print('set', key, val);
// may also capture (virtualize) write, or reject write
targ[key] = val;
return true; // indicate write was allowed
}
});
print(proxy.foo);
proxy.bar = 123;
Running with "duk" this prints:
get foo
hello
set bar 123
I have a function that handles two types: NVector and NMatrix; the former is derived from the latter. This function is basically a specialized copy constructor. I want it to return an object of the same type as that upon which it was called, so, NVector returns NVector, not NMatrix.
static VALUE nm_init_modifiedcopy(VALUE self) {
// ... some code ...
// formerly, I had cNMatrix where klass is. But it could also be cNVector!
return Data_Wrap_Struct(klass, mark_func, delete_func, unwrapped_self_copy);
}
How do I get the class property of an object to pass into Data_Wrap_Struct?
Like clockwork, as soon as I ask a question on Stackoverflow, I find the answer.
The macro is CLASS_OF.
static VALUE nm_init_modifiedcopy(VALUE self) {
// ... some code ...
return Data_Wrap_Struct(CLASS_OF(self), mark_func, delete_func, unwrapped_self_copy);
}