Code Monkey home page Code Monkey logo

Comments (24)

surma avatar surma commented on September 26, 2024

So there’s 2 things that stand out to me:

  • In the iframe you are exposing the Comunication class(!), not an instance. Then in the LoginCmpstComponent you are creating a new instance in the login() method, which never gets used? Not quite sure what your intention was here.
  • Because you exposed the Comunication class, the api constant in the parent would be that class. You could use it like const instanceOfComunication = await new api();, yet you are using it kinda like an instance (although I am not sure why you are accessing prototype.)

Hope this helps.

from comlink.

daniele-zurico avatar daniele-zurico commented on September 26, 2024

Hi Surma,
thanks for your reply.
My idea is when the iframe do login it increment the counter com.inc();.
The main application (is an angular2 app) check what is the value of the counter calling get counter().
If I understood well what you suggesting is to do that in the main app:

public async main() {
        const ifr = document.querySelector('iframe');
        const api = Comlink.proxy(Comlink.windowEndpoint(ifr.contentWindow));
        const instanceOfComunication = await new api();
        alert(instanceOfComunication.counter());
    }

But also in that way typescript is not happy because it complain: Cannot use 'new' with an expression whose type lacks a call or construct signature.
I think that we cant use await with new.

from comlink.

surma avatar surma commented on September 26, 2024

Oh my bad. I didn’t see you were using Comlink.expose({Comunication}) and not Comlink.expose(Comunication).

So you’d have to use const instanceOfComunication = await new api.Comunication();

from comlink.

daniele-zurico avatar daniele-zurico commented on September 26, 2024

but this is the point! api doesn't have a Comunication so the main project will complain saying:
property 'Comunication' does not exist on type 'Function'.

from comlink.

surma avatar surma commented on September 26, 2024

api is a proxy. It should never throw that error. Something must be missing.

Here’s a glitch for you to look at: https://glitch.com/edit/#!/comlink-issue-7?path=index.html

from comlink.

daniele-zurico avatar daniele-zurico commented on September 26, 2024

oh no no sorry my bad. is just the typescript runtime compiler that is complaining because Comunication do not exists and I don't know how to tell him to ignore the compilation of that line

from comlink.

surma avatar surma commented on September 26, 2024

const instanceOfComunication = await new (api as any).Comunication(); 😉

from comlink.

daniele-zurico avatar daniele-zurico commented on September 26, 2024

Last question. Is it correct in the iframe doing that:

constructor() {
            Comlink.expose({Comunication}, Comlink.windowEndpoint(self.parent));
    }

public login(value: any): void {
        this.displayErrorMessage = false;
        this.userService
            .authenticate(new Login(value.username, value.password))
            .subscribe((response: any) => {
                const com: Comunication = new Comunication(); <---
                com.inc(); <----
            }, err => this.displayErrorMessage = true);
    }

Because looks like that it's still complaining
screen shot 2017-09-18 at 10 55 45

from comlink.

surma avatar surma commented on September 26, 2024

I am not sure. I don’t think so. You are exposing the class. The login you are creating a new instance of that class. And you are creating yet another instance in the parent using Comlink. I think you might want a Singleton here.

from comlink.

daniele-zurico avatar daniele-zurico commented on September 26, 2024

I tried but still no luck:
LIBRARY:

import {Comlink} from 'comlinkjs';

export class Comunication {
    private static instance: Comunication;
    private _counter;

    constructor() {
        this._counter = 0;
    }

    public static getInstance() {
        if (!Comunication.instance) {
            Comunication.instance = new Comunication();
            // ... any one time initialization goes here ...
        }
        return Comunication.instance;
    }

    public get counter() {
        return this._counter;
    }

    public inc() {
        this._counter++;
    }
}

Comlink.expose({Comunication}, Comlink.windowEndpoint(self.parent));

IFRAME COMPONENT:

const add = Comunication.getInstance();
add.inc();

PARENT:

public async main() {
        const ifr = document.querySelector('iframe');
        await new Promise(resolve => ifr.onload = resolve);
        const api = Comlink.proxy(Comlink.windowEndpoint(ifr.contentWindow));
        const instanceOfComunication = await (api as any).Comunication.getInstance();
        console.log(await instanceOfComunication.counter);
        await instanceOfComunication.inc();
        console.log(await instanceOfComunication.counter);
    }

No able to find the method .inc()

from comlink.

surma avatar surma commented on September 26, 2024

You need to use return Comlink.proxyValue(Comunication.instance). Only values created with new are implicitly proxied.

I should write an example for this!

from comlink.

surma avatar surma commented on September 26, 2024

Also heads up: I am about to remote windowEndpoint in the next release.

from comlink.

daniele-zurico avatar daniele-zurico commented on September 26, 2024

Sorry I don't understanf . Instead to do:

const api = Comlink.proxy(Comlink.windowEndpoint(ifr.contentWindow));

I should do what?

from comlink.

surma avatar surma commented on September 26, 2024

Take a look at the examples. I updated them.

from comlink.

daniele-zurico avatar daniele-zurico commented on September 26, 2024

You mean just to change:

const api = Comlink.proxy(Comlink.windowEndpoint(ifr.contentWindow));

in that:

const api = Comlink.proxy(ifr.contentWindow);

??
Before you said that:
You need to use
return Comlink.proxyValue(Comunication.instance).
Only values created with new are implicitly proxied.

from comlink.

surma avatar surma commented on September 26, 2024

Those are two completely separate things. You need to use proxyValue in your getInstance() method and – once you update to Comlink 2.0 – need to remove windowEndpoint.

from comlink.

daniele-zurico avatar daniele-zurico commented on September 26, 2024

omg I don't have any clue what I've to change. Do you prefer that I create a simple repro on my github? I'm using angularcli

from comlink.

surma avatar surma commented on September 26, 2024

You only need to change the two things in mentioned in my last post:

  • use proxyValue in your getInstance() method
  • don’t use windowEndpoint

from comlink.

surma avatar surma commented on September 26, 2024

Here you go: https://glitch.com/edit/#!/comlink-issue-7

from comlink.

daniele-zurico avatar daniele-zurico commented on September 26, 2024

So with 1.2 it doesn't work:
Code:

Library:

import {Comlink} from 'comlinkjs';

export class Comunication {
    private static instance: Comunication;
    private _counter;

    constructor() {
        this._counter = 0;
    }

    public static getInstance() {
        if (!Comunication.instance) {
            Comunication.instance = new Comunication();
        }
        return Comlink.proxyValue(Comunication.instance);
    }

    public get counter() {
        return this._counter;
    }

    public inc() {
        this._counter++;
    }
}

Comlink.expose({Comunication}, Comlink.windowEndpoint(self.parent));

Iframe:

const add: any = Comunication.getInstance();
add.inc();

Main:

        const ifr = document.querySelector('iframe');
        await new Promise(resolve => ifr.onload = resolve);
        const api = Comlink.proxy(Comlink.windowEndpoint(ifr.contentWindow));
        const instanceOfComunication = await (api as any).Comunication.getInstance();
        console.log(await instanceOfComunication.counter);
        await instanceOfComunication.inc();
        console.log(await instanceOfComunication.counter);
    }
Uncaught (in promise): TypeError: Promise resolver null is not a function
TypeError: Promise resolver null is not a function

Maybe when you release 2.0 I can apply your change and it will work?

from comlink.

surma avatar surma commented on September 26, 2024

2.0 is already released. And as I said, you need to remove windowEndpoint once you switch to 2.0, not before.

from comlink.

surma avatar surma commented on September 26, 2024

Did you take a look at my glitch? I wrote it so you can study it and compare with your code.

from comlink.

daniele-zurico avatar daniele-zurico commented on September 26, 2024

Yep I applied all the changes apart

const api = Comlink.proxy(Comlink.windowEndpoint(ifr.contentWindow));
vs
const api = Comlink.proxy(ifr.contentWindow);
Comlink.expose({Comunication}, Comlink.windowEndpoint(self.parent));
vs
Comlink.expose({Comunication}, self.parent);

because my npm still doesn't find 2.0.0

from comlink.

daniele-zurico avatar daniele-zurico commented on September 26, 2024

ok updated to 2.0.0
now we have a cors problem:
the iframe is on localhost:4200
and the parent on localhost:4201

both are running with the --cors flag

SecurityError: Blocked a frame with origin "http://localhost:4201" from accessing a cross-origin frame.
Error: Blocked a frame with origin "http://localhost:4201" from accessing a cross-origin frame.
    at isWindow (comlink.es6.js:116)
    at Object.expose (comlink.es6.js:41)
    at Object.../../../../../src/app/common/comlink/Comunication.ts (Comunication.ts:27)

This is the place in your code where is breaking:

function isWindow(endpoint) {
        return endpoint.constructor.name === 'Window';
    }

from comlink.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.