2

I started new project from scratch on dart lang and was faced with a problem calling method of polymer element instance.

For example I have fps-counter element (fpsCounter.dart):

@HtmlImport('fps_counter.html')
library fpsCounter;
import 'package:web_components/web_components.dart' show HtmlImport;
import "package:polymer/polymer.dart";
import "dart:html";

@CustomTag("fps-counter")
class FpsCounter extends PolymerElement
{
    @observable
    int fps;

    // counter that will cleared at 60 ticks
    int _counter = 0;

    // accumulator delta time for 60 ticks
    int _accumulator = 0;

    factory FpsCounter() => new Element.tag('fps-counter');

    FpsCounter.created() : super.created() {
        polymerCreated();
    }

    bool calculateFps(double delta)
    {
        if (_counter == 60)
        {
            fps = (60000 / _accumulator).round();
            _counter = 0;
            _accumulator = 0;

            print("$fps FPS");

            return true;
        }

        _accumulator += delta;
        _counter++;

        return false;
    }
}

And want to invoke calculateFps(0.016) from out as in example below:

void _initRenderer(OSE ose)
{
    FpsCounter fpsCounter = new FpsCounter();
    fpsCounter.calculateFps(0.016);
    document.body.children.add(fpsCounter);

}

But faced with problem:

Exception: Uncaught Error: Class 'HtmlElement' has no instance method 'calculateFps'.

I really do not wanna create additional communication around that, any ideas how to make it better or how to invoke method? Thanks.

Also please to see additional files that can help:

pubspec.yaml

name: os
version: 0.0.1
dependencies:
  browser: ">=0.10.0 <0.11.0"
  ose:
    path: ./libs/ose
  polymer: any
transformers:
  - polymer

fps-counter.html

<link rel="import" href="packages/polymer/polymer.html" />
<polymer-element name="fps-counter">
    <template>
        <div>
            {{fps}} FPS
        </div>
    </template>
    <script type="application/dart" src="fpsCounter.dart"></script>
</polymer-element>
Community
  • 1
  • 1
  • This usually just works. There has to be some mistake that prevents the element to become a real `FpsCounter`. Can you create a public GitHub repo of the project? – Günter Zöchbauer Nov 03 '15 at 15:23
  • You don't need to call `polymerCreated();` in the constructor, except when your element extends a DOM element (like input). I would expect this to cause problems. – Günter Zöchbauer Nov 03 '15 at 15:24
  • Thanks, I'll remove polymerCreated(), but problem is not resolved. –  Nov 03 '15 at 15:29
  • Please create a GitHub repo so I'm able to properly investigate. Does your `pubspec.yaml` contain your entry page in the `polymer` transformer section? I can't know if your `pubspec.yaml` above is truncated because you think the content is not relevant to the question or whether there actually isn't any further content. – Günter Zöchbauer Nov 03 '15 at 15:31
  • I have create temporary repo: https://github.com/AndyTyurin/os Thanks for support! –  Nov 03 '15 at 15:37

1 Answers1

0

This looks like upgrading your custom element failed, probably due to an missing import. Otherwise FpsCounter fpsCounter = new FpsCounter(); would return a real FpsCounter instance and calling calculateFps(...) would work.

Add on top of your fps_counter.dart file:

@HtmlImport('fps_counter.html')
library some_library;
import 'package:web_components/web_components.dart' show HtmlImport;

You need to add the entry page to the pubspec.yaml polymer transformer section

transformers:
  - polymer:
      entry_points:
      - web/index.html

You need to import the dart file containing the class FpsCounter otherwise you can't use FpsCounter as type annotation or.

You need to keep the FpsCounter.created() : super.created() constructor, just don't call polymerCreated() inside it if you don't extend a DOM element.

I also had to change your main() method. The way you initialized Polymer works only for >=1.0.0-rc.x but with any you don't get pre-releases but you get 0.16.3+3 instead. See also how to implement a main function in polymer apps

import 'os.dart';
import 'package:polymer/polymer.dart';
export 'package:polymer/init.dart';

@whenPolymerReady
init() async {
  OS os = new OS();
  os.start();
}

Now it's working

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Thanks for answer. I think there is another problem, I updated code at top of question and added additional files to help. Also I have several errors in IDE: 1) [Warning from HtmlFinalizer on os|web/components/fps/fps_counter.html]: line 1, column 1 of web/components/fps/fps_counter.html: (from html) Unexpected start tag (html). Expected DOCTYPE. 2) [Warning from HtmlFinalizer on os|web/index.html]: line 316, column 19 of web/index.html: The css file lib/src/build/log_injector.css was inlined multiple times. –  Nov 03 '15 at 15:22
  • These errors should be fixed already (recently, don't know which version). A polymer element doesn't need a ` `. – Günter Zöchbauer Nov 03 '15 at 15:27
  • `css file lib/src/build/log_injector.css was inlined multiple times` is just a hint for a possible optimization and could be fixed with an additional line in `pubspec.yaml` like `polymer: inline_stylesheets: log_injector.css: false` – Günter Zöchbauer Nov 03 '15 at 15:29
  • Problem with log_injector.css resolved, thanks! In bottom of my console of dartium I've got that: `Unsupported operation: Class is missing constructor FpsCounter.created` –  Nov 03 '15 at 15:34
  • Thanks! I hope that it should help to solve problem, I will check it soon when will be at home. –  Nov 03 '15 at 16:17
  • It worked for me. At least the up to the line where `calculateFps()` was called. Didn't look what the code does afterwards ... – Günter Zöchbauer Nov 03 '15 at 16:18
  • 1
    Oh, you made my day. Afterwards nothing for now. I want to put element to my renderer pipeline that invokes render method each frame (requestAnimationFrame), also want to setup delta param for element before update that is needed to calculate fps (renderer will invokes calculateFps method and then display it on dom). In whole it will be small game engine based on sprites with using power of webgl, it's my small investigation. Thanks a lot! –  Nov 03 '15 at 22:41