Flex resourceManager working perfect in one file and not at all in another - actionscript-3

I'm trying to use resourceManager in Flex for some localization. I'm having a strange problem where it works fine in the first file that I tried it in, but in the second it won't even compile.
Both files have
import mx.resources.ResourceBundle;
at the top and
[ResourceBundle("Hurley")]
above the class definition. The first one compiles fine, and pulls the text from the resources correctly at runtime.
The second file (which is in the same project but a different folder), will not compile, and every mention of resourceManager gives an error of "1120: Access of undefined property resourceManager."
For the two different uses:
In the file that works:
public function SeasonsComboBox() {
this.labelFunction = function(obj:Object):String {
return resourceManager.getString('Hurley','Season_word') + " " + obj.number;
};
}
And the file that doesn't work:
public function getCarousels(seriesId:String, callback:Function):void {
[...]
ExternalInterface.addCallback("getCarouselsFailure", function():void {
Alert.show(resourceManager.getString('Hurley','CarouselsFailure_text'), "Error", Alert.OK);
});
[...]
}
I can't think of anything different I did in either file.
Edit, Solved:
resourceManager is defined in all UIComponent subclasses. The file that worked imported ComboBox. The files that didn't don't. In those files, I can make it work by calling:
ResourceManager.getInstance()
More information here: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/resources/IResourceManager.html

The reason that you can't access the reourceManager property, is because it is probably not defined.
It is defined in UIComponent, so any class that extends a UIComponent that will have it defined. But, otherwise you have to define it yourself.
You can do so using something like this:
public var resourceManager:ResourceManager = ResourceManager.getInstance();

Related

Typescript return HTML Template Element from Constructor typing not working

It is 'illegal' to use new when creating an instance of Template, where Template extends an HTMLTemplateElement.
To overcome this limitation, I get and return an HTMLTemplateElement using document.getElementById(id) from the Template constructor as below:
export class Template {
private htmlTemplateElement: HTMLTemplateElement;
constructor(id: string) {
this.htmlTemplateElement = document.getElementById(id) as HTMLTemplateElement;
return Object.assign(this.htmlTemplateElement, this)
}
public test = () => this.htmlTemplateElement.innerHTML
}
Providing an HTML Template Element exist in the DOM,
I can create a new instance of Template and use the extension method test() as illustrated below:
const template = new Template(id)
console.log(template.test())
console.log(template.innerHTML)
Both console.log() works just fine and prints the correct text to the console.
HOWEVER, the typescript compiler complains about template.innerHTML.
The error I get, saying innerHTML does not exist on type Template
Question: How can I add type information so I do not get a compiler error?
I have tried to use export class Template extends HTMLTemplateElement.
That does not work since it is illegal to create an instance using new.
I love typescript, but sometimes the type checking gets in my way.
Help me out here, please.
Although not ideal, I was able to keep the typescript compiler happy by implementing the following interface:
export interface ITemplate {
[key:string]: any;
test(): string;
}
and then using the interface:
export Template implements ITemplate {
...
}
Note:
Why did I not use customElements.define(<tag-name>,Template)?
I do not intend to create a new custom instance of HTMLTemplateElement, I just want to return an existing HTMLTemplateElement with additional utility extension methods.
Also, It might very well be possible that my approach is completely wrong.
However, that is a different topic than the question asked here.

Custom error classes not extending correctly [duplicate]

I'm trying to throw a custom error with my "CustomError" class name printed in the console instead of "Error", with no success:
class CustomError extends Error {
constructor(message: string) {
super(`Lorem "${message}" ipsum dolor.`);
this.name = 'CustomError';
}
}
throw new CustomError('foo');
The output is Uncaught Error: Lorem "foo" ipsum dolor.
What I expect: Uncaught CustomError: Lorem "foo" ipsum dolor.
I wonder if that can be done using TS only (without messing with JS prototypes)?
Are you using typescript version 2.1, and transpiling to ES5? Check this section of the breaking changes page for possible issues and workaround: https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
The relevant bit:
As a recommendation, you can manually adjust the prototype immediately after any super(...) calls.
class FooError extends Error {
constructor(m: string) {
super(m);
// Set the prototype explicitly.
Object.setPrototypeOf(this, FooError.prototype);
}
sayHello() {
return "hello " + this.message;
}
}
However, any subclass of FooError will have to manually set the prototype as well. For runtimes that don't support Object.setPrototypeOf, you may instead be able to use __proto__.
Unfortunately, these workarounds will not work on Internet Explorer 10 and prior. One can manually copy methods from the prototype onto the instance itself (i.e. FooError.prototype onto this), but the prototype chain itself cannot be fixed.
The problem is that Javascript's built-in class Error breaks the prototype chain by switching the object to be constructed (i.e. this) to a new, different object, when you call super and that new object doesn't have the expected prototype chain, i.e. it's an instance of Error not of CustomError.
This problem can be elegantly solved using 'new.target', which is supported since Typescript 2.2, see here: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html
class CustomError extends Error {
constructor(message?: string) {
// 'Error' breaks prototype chain here
super(message);
// restore prototype chain
const actualProto = new.target.prototype;
if (Object.setPrototypeOf) { Object.setPrototypeOf(this, actualProto); }
else { this.__proto__ = actualProto; }
}
}
Using new.target has the advantage that you don't have to hardcode the prototype, like some other answers here proposed. That again has the advantage that classes inheriting from CustomError will automatically also get the correct prototype chain.
If you were to hardcode the prototype (e.g. Object.setPrototype(this, CustomError.prototype)), CustomError itself would have a working prototype chain, but any classes inheriting from CustomError would be broken, e.g. instances of a class VeryCustomError < CustomError would not be instanceof VeryCustomError as expected, but only instanceof CustomError.
See also: https://github.com/Microsoft/TypeScript/issues/13965#issuecomment-278570200
As of TypeScript 2.2 it can be done via new.target.prototype.
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#example
class CustomError extends Error {
constructor(message?: string) {
super(message); // 'Error' breaks prototype chain here
this.name = 'CustomError';
Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
}
}
It works correctly in ES2015 (https://jsfiddle.net/x40n2gyr/). Most likely, the problem is that the TypeScript compiler is transpiling to ES5, and Error cannot be correctly subclassed using only ES5 features; it can only be correctly subclassed using ES2015 and above features (class or, more obscurely, Reflect.construct). This is because when you call Error as a function (rather than via new or, in ES2015, super or Reflect.construct), it ignores this and creates a new Error.
You'll probably have to live with the imperfect output until you can target ES2015 or higher...
I literally never post on SO, but my team is working on a TypeScript project, and we needed to create many custom error classes, while also targeting es5. It would have been incredibly tedious to do the suggested fix in every single error class. But we found that we were able to have a downstream effect on all subsequent error classes by creating a main custom error class, and having the rest of our errors extend that class. Inside of that main error class we did the following to have that downstream effect of updating the prototype:
class MainErrorClass extends Error {
constructor() {
super()
Object.setPrototypeOf(this, new.target.prototype)
}
}
class SomeNewError extends MainErrorClass {}
...
Using new.target.prototype was the key to getting all of the inheriting error classes to be updated without needing to update the constructor of each one.
Just hoping this saves someone else a headache in the future!
I ran into the same problem in my typescript project a few days ago. To make it work, I use the implementation from MDN using only vanilla js. So your error would look something like the following:
function CustomError(message) {
this.name = 'CustomError';
this.message = message || 'Default Message';
this.stack = (new Error()).stack;
}
CustomError.prototype = Object.create(Error.prototype);
CustomError.prototype.constructor = CustomError;
throw new CustomError('foo');
It doesn't seem to work in SO code snippet, but it does in the chrome console and in my typescript project:
I was having this problem in a nodejs server. what worked for me was to transpile down to es2017 in which these issues seems to be fixed.
Edit tsconfig to
"target": "es2017"
Try this...
class CustomError extends Error {
constructor(message: string) {
super(`Lorem "${message}" ipsum dolor.`)
}
get name() { return this.constructor.name }
}
throw new CustomError('foo')

How to pass an object to child component while creating it in HTML template markup?

I'm doing the following (it's working as expected) in my parent component.
<app-textbox [info]="{caption:'Boink',value:'Oink'}"
... ></app-textbox>
In the receiving child component I have the following declaration.
#Input() info: any;
Now I want to improve the code and make it hard-typed, so I introduced and imported the following class.
export class TextBoxInfo { constructor(public caption: string, public value: string) { } }
Then, I updated the child component's input as follows.
#Input() info: TextBoxInfo;
Everything still works, as expected but I also wanted to improve the markup in HTML by switching to the following syntax.
<app-textbox [info]="new TextBoxInfo('Boink','Oink')"
... ></app-textbox>
That doesn't work and I'm getting the error message .
Uncaught Error: Template parse errors:
Parser Error: Unexpected token 'TextBoxInfo' at column 5 in [new TextBoxInfo('Boink', 'Oink')]
in ng:///AppModule/ParentComponent.html#45:24 ("
/div>
app-textbox [ERROR ->][info]="new TextBoxInfo('Boink', 'Oink')" ...
I've try to google to confirm or contradict that I can use the syntax like new Something(...) in the template's markup. Nothing conclusive this far. I also tried to google for the error but it's simply telling me that the syntax isn't recognized. I haven't found any viable examples of how to create an object and pass it in the template and googlearching it is complicated by the lack of good key words.
Am I approaching the object creation incorrectly?
Using type literals in templates is not supported. The scope of a template is the component instance, and therefore only properties of the component instance can be accessed.
If you need to reference identifiers outside of that scope, you need to move the code/expression to the components class and expose it to the template from there.
class MyComponent {
createTextBoxInfo(p1, p2):TextBoxInfo { return new TextBoxInfo(p1, p2); }
}
[info]="createTextBoxInfo('Boink','Oink')"
while this concrete case is a bad example in practice.
It would create a new TextBoxInfo every time change detection is run which is probably not what you want and will bring the performance of your app to its knees.
It's better to assign the value to a property and bind to that instead:
class MyComponent {
textBoxInfo = new TextBoxInfo('Boink','Oink'); }
}
[info]="textBoxInfo"

PHP namespace behaviour gives FATAL error with spl_autoload_register

I want to use namespace and spl_autoload_register together but failed with different error each time.
Please See complete code files on github.
Below are the files
a base file where create a class with namespace class.alpha.php
an include file where I define spl_autoload_register include.php
an example file which instantiate the class object eg.php
Now when I create object from eg.php it gives FATAL error but when I comment namespace line in class.alpha.php then it's working
Please see the code below.
alpha.class.php
<?php
//namespace Alpha; //<< comment and uncomment this to regenerate the error
class Alpha
{
// public static $baseDir_;
public $dir = __DIR__;
public static $baseDir_;
public function __construct()
{
echo __FILE__."=>".__METHOD__;
var_dump(self::$baseDir_, $this->dir);
$firstDir = !empty(self::$baseDir_) ? self::$baseDir_ : $this->dir;
}
}
include.php
<?php //namespace Alpha\config;
spl_autoload_extensions(".php");
spl_autoload_register('loadclass');
function loadclass($class)
{
try {
if (is_readable(strtolower($class).".class.php")) {
include_once strtolower($class).".class.php";
}
} catch (Exception $e) {
print "Exception:". $e;
}
}
//#link http://php.net/manual/en/function.spl-autoload-register.php
// spl_autoload_register(__NAMESPACE__.'Alpha\Alpha()' );
eg.php
<?php
require_once 'include.php';
/** below code works by commenting 1st line on alpha.class.php
if we un comment then below code gives Fatal error: Class 'Alpha' not found */
Alpha::$baseDir_ = '/opt/lampp/archive/';
$obj_ = new Alpha();
var_dump(get_included_files());
var_dump($obj_);
/** now we define namespace Alpha on alpha.class.php */
// $ns_ = new Alpha\Alpha(); // Fatal error: Class 'Alpha\Alpha' not found
// var_dump($ns_);
/** not working even with use statement */
// use Alpha;
// use Alpha;
// $fn = new Alpha\Alpha();
// var_dump($fn);
Please help me out to solve this issue.
Thanks
Your autoloader is receiving a request for a class of "Alpha\Alpha" if you uncomment the namespace in alpha.class.php and place the use Alpha\Alpha in eg. This means that the location it's expecting to find your class in would be alpha\alpha.class.php.
Unless you're on Windows, directory separators are typically forward slash (/). So there's a number of possible solutions.
**Possible Solution #1 - Leave all files in the same place **
If you want to leave everything where it is now, you'll need to remove the namespace from the class names in the autoloader. If you add these lines to the top of your autoloader, that will make it behave that way:
$classParts = explode("\\", $class);
$class = $classParts[count($classParts) - 1];
I would not recommend this solution though since it means that you can no longer provide the same class name in a different namespace.
Possible Solution #2 - Put namespaces in subdirectories
For this solution, you'd create a new directory "alpha" and move "alpha.class.php" into it. For autoloader changes, you can add the following lines to the top of your autoloader:
$class = str_replace("\\", "/", $class);
This will change the namespace separators from backslashes to file path separators with forward slash. This will work on windows as well as mac and linux.
Possible Solution #3 - Follow an established autoloading standard
There are already a number of standard PHP autoloading standards. PSR-0 (now deprecated) works, but PSR-4 would be recommended:
PSR-0: http://www.php-fig.org/psr/psr-0/
PSR-4: http://www.php-fig.org/psr/psr-4/
One big upside of following one of these standards is that there are already plenty of implementations for them and there's been a lot of thought put into how they should work and maintain compatibility with other libraries you may end up wanting to use. Composer (http://getcomposer.org) will allow you to set up and use both PSR-0 and PSR-4 style autoloaders based on a very simple configuration.
Anyway, for the TL;DR crowd, the issue is that the autoloader receives the entire namespaced path in order to know how to load the class. The fatal error was because the autoloader wasn't properly mapping from that namespaced class to a file system location, so the file containing the class was never being loaded.
Hope this helps.

Custom Neo4j GraphViz Writer

I have an application which produces a GraphViz dot file for a subgraph of my Neo4j database. It works like a charm, but there is somewhat of an issue.
Right now, the title of each node is the node id. Then the properties are listed, with their respective types. This is more information than I need and I would like to change the way the GraphViz writer is configured.
I noticed several classes/interfaces such as GraphStyle, StyleParameter, StyleConfiguration but I've tried several things and keep running into the issue that I cannot access certain classes/interfaces outside of their respective package. Maybe I'm doing it wrong, maybe it's designed so users cannot reconfigure the GraphViz writer, I don't know but I'd like to know.
How do I reconfigure the GraphViz writer so the dot file contains only that information which I want it to contain, namely a property of my choosing as the title, and nothing else as far as the nodes are concerned. Also, this is not always the same property, so for some nodes I'd like property A to be the title, and for nodes that don't have property A, I'd like property B to be the title.
Any help would be greatly appreciated.
You could try using the styles provided by this class: https://github.com/neo4j/neo4j/blob/master/community/graphviz/src/main/java/org/neo4j/visualization/graphviz/AsciiDocSimpleStyle.java
It might be useful to look into this class as well: https://github.com/neo4j/neo4j/blob/master/community/graphviz/src/main/java/org/neo4j/visualization/asciidoc/AsciidocHelper.java
I managed to get it to work. First of all, you need to create two new classes:
class NodeStyleImpl implements NodeStyle
class RelationshipStyleImpl implements RelationshipStyle
Here you can define how nodes and relations should be written in the dot notation. An example implementation looks like this :
public class NodeStyleImpl implements NodeStyle {
public void emitNodeStart(Appendable apndbl, Node node) throws IOException {
apndbl.append(" N" + node.getId() + " [\n label = \"");
}
public void emitEnd(Appendable apndbl) throws IOException {
apndbl.append("\"\n]\n");
}
public void emitProperty(Appendable apndbl, String propkey, Object propvalue) throws IOException {
if(propkey.equals("propkeyone") || propkey.equals("propkeytwo"){
apndbl.append(propvalue.toString());
}
}
}
In an analog fashion, you can write the RelationshipStyleImpl. If you're looking for more advanced configuration, you can also write a StyleConfiguration implementation. You can look at the default implementations in the Neo4j code for an example.
Then there's the issue with the GraphStyle class. The GraphStyle class has a constructor which is protected, thus only accessible from within the package. I made a pull request to change it to public but for the moment, here's a little "hack" which provides a workaround.
package org.neo4j.visualization.graphviz
public class GraphStyleImpl extends GraphStyle {
private GraphStyleImpl (NodeStyleImpl nstyle, RelationshipStyleImpl rstyle) {
super(nstyle, rstyle);
}
}
Note the package declaration. Because the GraphStyle constructor is protected, the super(nstyle, rstyle) method is only accessible from within the same package. By extending the class with a new public constructor, you can now do the following:
GraphStyle graphstyle = new GraphStyleImpl(new NodeStyleImpl(), new RelationshipStyleImpl());
GraphvizWriter writer = new GraphvizWriter(graphstyle);
If my pull request gets accepted, the use of the GraphStyleImpl class will no longer be necessary.