jeudi 31 octobre 2019

emberjs: Glimmer web component pass array/objects not working

One of our business problem statement is, we have to create component such that any consumer can use them as a widget and embed in their website. And the thing is we already have those component made with ember.

We're not aware that which stack the consumer website going to have, that could be random. So we thought of converting these ember components to web components.

We did small POC where we were not able to create web component out of ember component using glimmer. But we're facing couple of problems

  1. We're not able to pass objects/arrays to web components with glimmer (we tried using pass it through properties)
  2. Somehow shadow DOM is not working when web component gets rendered

For using simple glimmer component I have followed https://glimmerjs.com/guides/using-glimmer-as-web-components




How to replace the authorize method in ember-simple-auth

I'm trying to refactor my Ember acceptance tests to not use the deprecated authorize method, as it is throwing a warning:

The `authorize` method should be overridden in your application adapter

I checked the docs, and numberous other sources, but they don't actually explain how to migrate my code. Here's what I've got at the moment:

// projectname/app/pods/login/controller.js (excerpt)
export default Controller.extend({
    session: service(),
    sessionToken: null,

    onSuccess: function(res) {
    res = res.response;
        this.set('sessionToken', res.session);
        if (res.state === "authenticated") {
            document.cookie = "token="+res.session+";path=/;";
            var authOptions = {
                success: true,
                data : {
                    session : res.session,
                }
            };
            this.get('session').authenticate("authenticator:company", authOptions);
        }
    }
});

And this must be the part that I'm meant to get rid of:

// project/app/adapters/application.js (excerpt)
export default DS.RESTAdapter.extend(DataAdapterMixin, {
    authorize(xhr) { // This is deprecated! I should remove it
        let sessionToken = this.get('session.data.authenticated.session');
        if (sessionToken && !isEmpty(sessionToken)) {
            xhr.setRequestHeader('Authorization', "Token " + sessionToken);
        }
    },
});

And here is my test:

import { test, module } from 'qunit';
import { visit, currentURL, find, click, fillIn } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import { authenticateSession} from 'ember-simple-auth/test-support';

module('moduleName', function(hooks) {
    setupApplicationTest(hooks);

    test('moduleName', async function(assert) {
        // await authenticateSession(this.application); // Never works
        // await authenticateSession(); // Never works
        await authenticateSession({
            authenticator: "authenticator:company"
        }); // Works slightly more?
        await visit('/my/other/page');
        await assert.equal(currentURL(), '/my/other/page');
    });
});

REMOVING the authorize method and attempting either of the commented out methods yields:

Error: Assertion Failed: The `authorize` method should be overridden in your application adapter. It should accept a single argument, the request object.

If I use the authenticator block as an arg, then regardless of the presence of the authorize method, I simply get:

    actual: >
        /login
    expected: >
        /my/other/page

Which, I assume, is because it did not login.

Leaving the authorize method there, and trying the commented methods yields:

Error: Browser timeout exceeded: 10s



How to have dynamic values for queryParams in ember 2.17

I have a route where I want one of the params to be the first date of the previous month.

To do so I need to be able to dynamically set the start_date.

import Controller from '@ember/controller';

export default Controller.extend({
  queryParams: ['start_date'],
  start_date: "AAAAAA"
});

I tried to do it in the setupController :

setupController(controller, model) {
    this._super(controller, model);
    controller.set('start_date','BBBBBBBBB')
  }

But this is not correct :

1) it ignore a param passed via the URL. I want my dynamic value to act as a normal query param

2) The value of params in the model() is from the controller.

How can I have a synamic value (first day of last month) as the default value of a route's params ?




mercredi 30 octobre 2019

Convert Ember addon to web component

How to convert an ember addon to web component?

https://github.com/BBVAEngineering/ember-cli-web-components This plugin is not working, I am getting, defineCustomElements is not defined error.

Then I found glimmer can create web components. With glimmer, I need to convert ember addon to glimmer, then create web component (which is time consuming). Also I am not able to pass arrays and objects to web component created using glimmer (can only pass strings using atrributes) and the web component is not using shadow dom (which can cause problems with styling).

Ember octane is using glimmer component, but cannot find in its documentation if it can be converted to web component

So what is currently the best way to convert ember addon to web component?




Return promises from Ember 2.16 Component Integration Tests Mocked action

I am creating tests for my Ember 2.16 application, and running into an issue where the code is dependent on a promise being returned from an external action.

const promise = this.sendAction('action')
promise.then(() => {
  //do stuff
});

A majority of my code is based in these .then and .catch conditionals on the promise, so I want to be able to return a promise that was successful and that failed. I have heard of Sinon, but unfortunately it is only for Ember 3.4 and above.

test('', function(assert){
  this.set('action', () => {
    // do assertions
    return new Promise(() => {return true} );
  });
});

Inside my integration test I am able to mock out the action, but I run into the "promise" being undefined. I have attempted to return Text, or other values, but when putting a debugger into the component the promise is always undefined.

I can get around this by adding a conditional that checks to see if there is a promise, but since the majority of my code is inside these .then and .catchconditionals I want my tests to step through these to increase the code coverage.

How would I return a promise from a mocked out action in an Integration Test?




Understanding the gulp and watch commands

I have a project which is running fine, I need to make some modifications in the project, but meanwhile I came across two commands that team is using on the project are gulp, ./watch, what are these commands for? This project is part of Visual Studio Solution, it has an Ember project, when ran the ./watch command, it posts the compiled javascript into a different UI project, so what are these commands, what should I do to use them more efficiently I want to have knowledge about it.

When I tried to find out the location of the gulp command, its in node_modules folder, but when I am reading online, it should be created by the developer, does it come as a package or do I have to make any changes? I want to understand what's it about?

What is ./watch command, like if I add any components or Services etc, should I make any changes to these commands, I got some sort of information online that these two commands are for deployment, which one should run first and which one should run next - any help please?




mardi 29 octobre 2019

Is it possible to make a redirect rule in the routerjs file to create a vanity route

To speak specifically, I have a URL to one page on a website but the URL is somewhat long and ugly.

It might look a little bit like this

mywebsite.com/all-products/hats/golf-caps

however, my marketing team feels this URL is too long and wants me to add a "prettified" url like this:

mywebsite.com/golf-caps

But all it would really do is redirect to the original route.

Is there a way to do this in ember.js? Or is this a bad practice? Ideally, I would only need to modify the router file rather than create a completely new route in my application just to perform a redirect.