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.




vendredi 25 octobre 2019

What are the separations of concerns for testing a component that consumes additional components

When writing tests for a web-component (parent) that consumes other web-components (children) should the parent's tests provide coverage to ensure the children are rendering/configured properly?

Here's an example, it might be a poor example, but's lets try: Say we have a component (WebComponent/React/Vue/Ember, any component will do here): <Carousel @options=options> which renders various children components: such as <Video @options=options> and <Image @option=options> and many others.

The Carousel component receives a set of options from the model, such as iconColor and objectFit, and passes that in a datadown fashion to share with and be consumed by the child components.

Should I be testing “user can configure iconcolor for image” in both my tests for the <Image> and <Carousel>?

It seems awkward to me and not very DRY to test for successful configuration of iconcolor in the respective tests for both <Carousel> and <Image>. If the <Carousel> component consumes 5 different components, its tests start scaling in size, especially if we add more config options.

But at the same time is seem very brittle not to have test coverage in both. For example, if we rely on <Image>'s test coverage for configuration of iconColor, <Image> could be refactored anytime and a developer could change the name of the property for setting iconColor, adjust the tests to match. The developer would be unaware that <Carousel> has a dependancy on <Image>'s API for configuring iconColor.




Updating from bubble action(sendAction()) to closure action

I'm trying to update my code to the latest version of ember and I want to avoid deprecations. I have read that using closure actions is more preferred over bubble actions. So I am currently updating my code to make it more usable.

Following is the code:

app/components/date-picker.js

actions: {
    onChange() {
      if (this.onChange) {
        this.sendAction('onChange');
      }
    }
  }

app/templates/components/date-picker.hbs


  <i class="calendar icon"></i>


Can anyone describe to me on how to update it so that I could use closure actions. Additional references to this would be helpful. Thanks




mercredi 23 octobre 2019

EmberJS and web components: extend an existing HTML tag within an initializer (is it possible?)

Edit: this issue only seems to be in the .hbs rendering as this code does work when the extended web component is inserted in the top level index.html of the EmberJS project

Edit 2: However, when I put it in a minimal .hbs example, then it did work. So it is clearly an interaction with EmberJS rendering and perhaps with Handlebars, somehow.

I am trying to understand how to use web components in EmberJS. I know that I could rewrite a web component into an EmberJS component, but that is not the point. I want to know how to directly integrate web components into EmberJS.

There is a tutorial that describes how to make custom web components and put that in EmberJS by making an initializer.

https://tenbit.co/blog/a-simple-way-to-integrate-web-components-with-your-ember-app/

So you'd think, that it is a piece of cake to do the same thing for an extended native HTML component right? It turns out that it isn't.

Here is a minimal example of what isn't working. In this particular example <p>hello world</p> gets displayed but <p>hello Mars</p> does not. However, in the standalone HTML file (see on the bottom of this post) which has the same classes and define() calls, then it does work.

I also made an EmberJS Twiddle, in which you can see it: https://ember-twiddle.com/5b85957f52aba288bfe9e94ce42b811e

// app/initializers/custom-elements.js
class HelloWorld extends HTMLElement {
  constructor() {
    super();
    console.log("constructor() HelloWorld");
    let shadowRoot = this.attachShadow({ mode: "open" });
    shadowRoot.innerHTML = `<p>hello world</p>`;
  }
}

//similar to HelloWorld -- it's simply an extension
class TestingAParagraph extends HTMLParagraphElement {
  constructor() {
    super();
    console.log("constructor() TestingAParagraph");
    let shadowRoot = this.attachShadow({ mode: "open" });
    shadowRoot.innerHTML = `<p>hello Mars</p>`;
  }
}

export function initialize(application) {
  window.customElements.define("hello-world", HelloWorld);
  window.customElements.define("testing-a-paragraph", TestingAParagraph, {
    extends: "p"
  });
}

export default {
  initialize
};

Here is the Handlebars file:


<p>Bladiebla</p>
<hello-world></hello-world>
<p>A test is coming</p>
<p is="testing-a-paragraph"></p>

Note: this minimal example does work as a standalone HTML file.

<!DOCTYPE html>
    <html>
    <head>
      <script type="text/javascript">
        // app/initializers/custom-elements.js
        class HelloWorld extends HTMLElement {
          constructor() {
            super();
            console.log("constructor() HelloWorld");
            let shadowRoot = this.attachShadow({ mode: "open" });
            shadowRoot.innerHTML = `<p>hello world</p>`;
          }
        }
    
        //similar to HelloWorld -- it's simply an extension
        class TestingAParagraph extends HTMLParagraphElement {
          constructor() {
            super();
            console.log("constructor() TestingAParagraph");
            let shadowRoot = this.attachShadow({ mode: "open" });
            shadowRoot.innerHTML = `<p>hello Mars</p>`;
          }
        }
    
    
        window.customElements.define("hello-world", HelloWorld);
        window.customElements.define("testing-a-paragraph", TestingAParagraph, {
          extends: "p"
        });
      </script>
    </head>
    <body>
      <p>Bladiebla</p>
      <hello-world></hello-world>
      <p>A test is coming</p>
      <p is="testing-a-paragraph"></p>
    </body>
    </html>



User loading after authentication with ember simple auth

I use ember simple auth to authenticate my users. It workls perfectly fine except when the user just logged in.

I have an helper that ask for the current user :

import Helper from '@ember/component/helper';
import { inject as service } from '@ember/service';

export default Helper.extend({
  currentUser: service('current-user'),
  compute([feature,currentUser]) {
    let role = currentUser.get('user.role')

Helper is used in a template embedded in a template in application.hbs


  <li><i class="fa fa-user"></i> <span>Clients</span></li>
  

The current user service is a duplicate of this one from the doc : https://github.com/simplabs/ember-simple-auth/blob/master/guides/managing-current-user.md#loading-the-user-with-its-id

And my application.js is also using the code from the same guide.

From what I tried, the sessionAuthenticated start to run, and during await this._loadCurrentUser(); the helper is executed, and it finish to run sessionAuthenticated

What happen is that the user attribute I want is undefined and it make it impossible to display interface elements according to the role of the User.

How can I fix this problem?

Edit for related question :How does ember simple auth is supposed to be used in template to determine if User is supposed to see some part of the interface or not ? Like for example menu choices.




How to check two values are equal in ember handlebar without checking its type?

-> matches type and returns false

Link:https://www.npmjs.com/package/ember-truth-helpers

eq if (a === b)

In documentation it is checking for type tooo

I have also tried using is-equal helper it too returns false....




mardi 22 octobre 2019

Ember concurrency timeout hanging in qunit

In Ember I have a component that starts a never-ending poll to keep some data up to date. Like so:

export default Component.extend({
  pollTask: task(function * () {
    while(true) {
      yield timeout(this.get('pollRate'));
      this.fetchSomeData();
    }
  }).on('init')
})

This causes a preexisting acceptance test to get stuck in this task and run forever, even though it should be run asynchronously. The test looks like this:

test('my test', async function(assert) {
  mockFindRecord(make('fetched-model'));

  await visit('/mypage'); // gets stuck here
  await typeIn('input', 'abc123');

  assert.ok(somethingAboutThePage);
});

I thought at first that I had mocked the request wrong and that the test was just timing out, but it was in fact correctly polling data. Removing this task makes the acceptance test finish normally.

Testing this manually seems to work fine, and nothing gets stuck. Why is this happening and what is the right way to address this?

Saw Unit testing ember-concurrency tasks and yields but it doesn't really help since it only deals with unit tests.




How to retrieve static data in Ember?

A few of my model have property with a list of state :

thing.js

...
status: DS.attr('number'),
statesValues: {1 : "First",2: "Some Choice", 3: "Nothing"}
...

How can I in another ember object, access the values from the Thing model ? I tried to Import the model but I do not even know the correct path to import.




lundi 21 octobre 2019

Implementing Routes in Ember Addon

I am new to ember. I am planning to create an addon to share across the application. My addon having screens to navigate. I have no idea how to apply the routes or implementing routes inside ember addon. And moreover, I want to share the addon with consuming application also. Can anyone suggest with any simple example on how to implement ?




Disadvantages of implementing WebSockets without Ember Service

I need to know what are all the disadvantages of implementing WebSockets in a Ember app without Ember Service. A lot of tutorials in the internet have mentioned that Ember Service is useful in implementing WebSockets. But none of them has listed out its advantages of using Ember Service in this case and disadvantages of not using that.

Can someone who is aware of this share their knowledge here or redirect me to a proper URL?




why are you still use emberjs in your project?

In China,I found a little of developers use Emberjs,and lot of developers use Reactjs & Vue. I want to know why are you choose Emberjs if you use Emberjs.




dimanche 20 octobre 2019

How to handle keypress event properly in Ember js 3.13

I'm new to Ember & I want to catch a global key press event and handle it in my component.

After a lot of web crawling I did it the old fashion way with global window.onkeydown = this.handleKeyPress & at the handleKeyPress function i did some code and call this.movePlayerInDirection but now my 'this' is the window.

onKeyPress(e, comp) { let keyCode = e.keyCode;

    if (keyCode === KEY_LEFT ||
        keyCode === KEY_UP ||
        keyCode === KEY_RIGHT ||
        keyCode === KEY_DOWN) {
        let direction;

        switch(e.keyCode) {
            case KEY_LEFT:
                direction = {x: -1, y: 0}
                break;
            case KEY_RIGHT:
                direction = {x: 1, y: 0}
                break;
            case KEY_UP:
                direction = {x: 0, y: -1}
                break;
            case KEY_DOWN:
                direction = {x: 0, y: 1}
                break;
        }
        this.movePlayerInDirection(direction);
    }
}
  1. Is this the best way to catch this event? (the ember way)

  2. How do i reach the component functions from the window scope?




vendredi 18 octobre 2019

Unit testing ember-concurrency tasks and yields

We have a lot of code in our project that isn't covered because of ember concurrency tasks.

Is there a straightforward way of unit testing an controller that contains something like the following:

export default Controller.extend({
    updateProject: task(function* () {
        this.model.project.set('title', this.newTitle);
        try {
            yield this.model.project.save();
            this.growl.success('success');
        } catch (error) {
            this.growl.alert(error.message);
        }
    })
});```



jeudi 17 octobre 2019

Creating integration tests in Ember 2.16 that utilize window.confirm()?

I am writing integration tests for an Ember 2.16 component and I am testing some user actions.

One of the user actions utilizes as window.confirm() functionality, where the user is asked if they are sure they want to delete an item before the item is deleted.

I want to test the functionality of this component, both with accepting and declining the confirm. The component action looks similar to this:

delete(id){
  if(confirm('Are you sure you want to delete?')){
    //do stuff
  } else {
    //do other stuff
  }
}

Inside my integration tests I am successfully clicking the button to bring up the prompt, but I am running into this error:

[Testem] Calling window.confirm() in tests is disabled, because it causes testem to fail with browser disconnect error.

How can I create an integration test that will bypass the window.confirm() functionality? I have added in my component a way to bypass the confirm if the env is in "test" mode, but this does not really help as I am not testing the portion of code that relies on the window.confirm().

I have looked around to see if there is a variable I can pass to the component to make the window.confirm() true/false, but have been unsuccessful.

How can I create a test that will test a component that has a window.confirm() function inside?




mardi 15 octobre 2019

How to create a record in ember.js while throwing a required data to it's relationship?

Please help me. I have a two model which are foo and bar models. I was trying to create a record on /foos endpoint using the POST /foos. However the post POST /foos has a requirement of relationships.bar.data.id=1,2,3. Please see my code below for /components/foo-bar.js. My question is how to create a foo record and declaring those ids to it's relationship?

/components/foo-bar.js

  foo.setProperties({
    bar: [1213,1231]
  });


 /models/foo.js
 import DS from 'ember-data';

  export default DS.Model.extend({
    bar:  DS.belongsTo('bar', { async: true }),
  });

  /models/bar.js
  import DS from 'ember-data';

  export default DS.Model.extend({
    foos:  DS.hasMany('foo', { async: true }),
  });



lundi 14 octobre 2019

I need to Customize the serializer in ember.js Adapter

My server needs json in the below format when sending a PUT request. My server is a rest api designed using struts2 rest plugin.

{
id: "5",
empId: "5",
firstName: "oki", 
lastName: "iko", 
edQual: "phd"
}
but the RESTAdapter serializes it to
[
employees:
 {
  id: "5", 
  empId: "5", 
  firstName: "oki", 
  lastName: "iko",
  edQual: "phd"
 }
]

I tried ignoring properties in backend but that just ignored the whole json and submitted null values to the sql-server. I need to override or customize the Serialization of ember.js but I dont know how.




vendredi 11 octobre 2019

Ember Js : How to share package json file dependency to child engines and addons

Basically I need to know how Ember Js can share parent app package.json file dependency(xyz:3.0.0) to child engine and addons without being used again in child engine and addon package.json file. So that I can reduce the size of the application.

As of now in our application we installing common package dependency in all our child engines and addons even though we used in parent app its increases application size.

Please help on this.




Upgrade to ember-typescript 3 complains about default parameters

Our Ember components often use the following pattern which is working as expected with ember-typescript 2:

export default class DatePicker extends Component {
  format: string = this.format || 'dd/LL/yyyy';
}

If format is not passed via the template it is initialized with 'dd/LL/yyyy'.

With ember-typescript 3 and the newer TS version the compiler is not happy anymore. It complains with

error TS2729: Property 'format' is used before its initialization.

as it is not happy with the usage of this.format.

What should I do to solve this problem? Is our code (which works fine so far) invalid and should be changed? If yes how?




Conditional Render in Loop

This is my first ever project with ember.

I'm trying to render a language-changer component. So far it renders ok, but I would like to append a spacer after each language as long and it is not the last one .

It should look something like

DE | FR | EN ...etc where | is actually a div

This is what I tried...

<div class="col-4 text-right language-changer">
  
    
      <span></span>
    
      <button > 
      </button>
    
    
      <div class="spacer">|</div>
    
  
</div>

I read, that the if only works on properties... but how can I evaluate based on the current loop index?

What should I use instead of

 

Thanks for the help.




jeudi 10 octobre 2019

ember.js - application level handling

I have a Ember.js 3.8 app in which I would like application level error handling. I've read what seems to be the relevant part of the documentation but it doesn't work as I expected.

I have a component to test this with :

exception-creator.hbs

<div class="panel panel-info">
  <div class="panel-heading">Development Only - Exception Creator</div>
  <div class="panel-body">
    <p>Press the button below to create an exception</p>
    <button >Throw an Exception</button>
  </div>
</div>

exception-creator.js

import Component from '@ember/component';

export default Component.extend({
  actions: {
    throw(){
      alert("About to throw an exception");
      throw new Error('Whoops!');
    }
  }
});

And (as per my reading of the doco) I have created a route application-error

application-error.hbs

<h1>Error Handler</h1>
<p>This is the error handler</p>

application-error.js

import Route from '@ember/routing/route';

export default Route.extend({
});

When the button is pressed I expected (after the alert) to be re-routed to the application-error template ... but I'm not. What does happen is that the debug console shows "Uncaught Error: Whoops!".

Would someone tell me where I'm going wrong please ?




Ember, change current url and link-to targets without reloading data

How to refresh url and link-to without reloading data?

Figure an app where a user can change the name of his project, then the current url must be refreshed since it contains the name of the project.

Nothing excepts the url must be modified (no data reload)

The replaceURL method allow to do that:

this.router.location.replaceURL(urlWithNewProjectName)

The problem is everywhere in the app the link-to components continue to target the old url.

How to set a segment path of the url, in order to update link-to in the app?




How to enable ds-rollback-attribute in ember?

Ember has method rollbackAttribute() which is very similar to the default method rollbackAttributes(). The difference is rollbackAttribute() can be used to rollback ONLY specific model attribute. By default this method is not available and to use it you need to enable ds-rollback-attribute and run the canary build as written here: https://docs.w3cub.com/ember/classes/ds.model/methods/#rollbackAttribute

Where can I enable the ds-rollback-attribute and how can I ran the canary build?




mercredi 9 octobre 2019

Audio tags inside Ember each loop

In an Ember application (Ember v3.13) I tried to iterate through an array of audio URLs, using an each loop in a template, and generate an audio tag for each...

I get the following error:

Assertion Failed: fullName must be a proper full name  

The audio tag works fine outside of the each loop.

Wondering if anybody has seen this before or know what it means or if there’s a workaround?




EmberJS: when not to use computed properties in services?

The EmberJS guides explain how computed properties work. They basically listen on changes and then a cascade wherever they're dependent on is recomputed.

I was wondering, can you create a service without computed properties? Are such services handy to have at any time?

I simply find it hard to understand when something should be and shouldn't be a computed property (other than internal variables that you simply use inside the function of a service, that should just be a normal variable).




Observe change of object proprty in nested array

We have this data structure

[[{foo:"12", bar:"34"}, {foo:"33", bar:"55"}], [{foo:"45", bar:"67"}]]

How is it possible to make a computed property to observe a change on foo or bar?




ember replaceWith does not changes the url

How to perform some replaceWith to the same route but with a different parameter?

The route declaration is:

this.route('sampleRoute', { path: '/:param_name' });

This 'sampleRoute' route reproduces the problem: the URL does not changes after a replaceWith inside it.

let globalFlag = null;

export default Route.extend({
  afterModel() {

    console.log("welcome");

    if(globalFlag){
      console.log(this.router.location.getURL());
      console.log(this.paramsFor(this.routeName).param_name);
    } else {
      globalFlag = true;
      this.replaceWith(this.routeName, 'progValue');
    }
  }
});

Tried with beforeModel, model, afterModel. How to have the URL properly set before running some code?

Testing this route with http://localhost/sampleRoute/browserValue produces:

Expected output: 
    welcome
    welcome
    /sampleRoute/progValue
    progValue

Actual output:
    welcome
    welcome
    /sampleRoute/browserValue
    progValue



Event delegation and the global `event` object in Ember action

Today I've learned a bit about the event delegation in Ember. The whole thing is exactly what I'd like to use in my code. There is a small problem though. When I migrate from

<div ondragend=></div>

to

<div ></div>

then I can't get the event parameter in my action method anymore and the thing is that I need it to get access to event.clientX/Y. This answer mentiones that it's possible to simply remove the parameter event and use it "globally" like this

...
actions: {
  dragEnd() {
    event.blahblah...
  }
}

So, I've got some questions regarding this technique:

  1. Can anyone tell me how legal is it? It's not documented anywhere.
  2. Do I understand correctly that in the case I use the closured action (<div ondragend=></div>) it won't use the event delegation, i.e. it will attach the event handler to that div and not the body like it does according to the doc if I use this pattern (<div ></div>) ?



using location in ember (how to lookup)

Trying to use the Location class with Ember 3.4.

How to instantiate/lookup/inject the Location class in my routes?

Writing this in a route file doesn't work:

import Location from '@ember/routing/location';

[...]

//in some action method
console.log(Location.getURL());

[...]

The result is:

getURL is not a function



mardi 8 octobre 2019

Add a querystring to an Ember Data REST adapter

I'm working on an existing EmberJS app, and need to make a small maintenance on it. My cases consists in adding a querystring parameter to a RESTAdapter.

I found the adapter in the following shape:

export default DS.RESTAdapter.extend({

   pathForType() {
       return 'myendpoints/-/endpoint1';
   },

   updateRecord(store, type, snapshot) {
       return this._super(store, type, snapshot).then(() => {
         // reload the artifact
         this.ajax(this._buildURL('my-artifact', snapshot.id));
       });
   },
})

I initially tried simply appending the querystring to the return of pathForType method, although it built the final url in the shape: domain.com/myendpoints/-/endpoint1?query=string/

Am I missing any detail? I see in the docs examples that do it that way: https://api.emberjs.com/ember-data/3.10/classes/DS.BuildURLMixin/methods?anchor=urlForUpdateRecord




samedi 5 octobre 2019

Are there any benefits to using GraphQL with React over using GraphQL with Vue/Ember/Angular?

Since GraphQL was developed by Facebook and React is also developed by Facebook I'm wondering if there are any benefits to using those two together as opposed to using a different javascript framework like Vue/Angular/Ember?




vendredi 4 octobre 2019

How to wrap handlebars expression in span tag, and make span tag clickable?

The datePick string is a computed property inside a button, you can click on datePick value to trigger an event, but clicking outside the datePick value inside the button does not trigger the event.

I tried wrapping it inside a span and giving width: 100% but still it is not clickable

<span>
      
</span>

I want it to occupy whole space inside a button and make it clickable everywhere.




mercredi 2 octobre 2019

Bypassing Ember validation while injecting a user and pass with jquery val

As a hobby I am trying to build my own username and password storage to inject via chrome plugin from site to site.

It works fine with the usual $('#username').val() However I am coming up against an issue on a site that was built with ember. The site has a form like this:

<form class="login_form" novalidate="" data-ember-action="" data-ember-action-7="7" _lpchecked="1">
    <div id="ember4" class="fieldset fieldset--error fieldset--empty fieldset--material ember-view"> <label for="username" class="fieldset_label">Username</label> <input name="username" id="username" class="input username" autocomplete="off" autofocus=""></div>
</form>

The problem is when I use $('#username').val("myUsername");

I get an error that says "please enter a username". The thing is if I go into the input, press any key, and then delete the text that I added it validates because it removes fieldset--error and fieldset--empty which then allows me to press submit and it works.

The thing is - how do I solve this in a programmatic way? Is there a way to tell Ember to stop pestering me to manually type instead of using .val()?

Or is there a way to trick it into thinking I did (because jquery.trigger doesn't work)




setApplication breaks ember-qunit test context

I recently upgraded an Ember app from 2.18 to 3.13 which went smoothly. Today I tried to add an acceptance test for the first time (only had integration / unit tests before this) but the test is failing on the first line:

import { module, test } from "qunit";
import { visit, currentURL } from "@ember/test-helpers";
import { setupApplicationTest } from "ember-qunit";

module("Acceptance | some route", function(hooks) {
  setupApplicationTest(hooks);

  test("visiting /some-route", async function(assert) {
    await visit("/some-route"); // <----- error thrown here

    assert.equal(currentURL(), "/some-route");
  });
});

I'm seeing a couple errors (in this order):

Source:     
TypeError: Cannot read property 'lookup' of undefined
    at Object.initialize (http://localhost:4200/assets/ritual-checkout.js:10312:28)
    at http://localhost:4200/assets/vendor.js:61627:21
    at Vertices.each (http://localhost:4200/assets/vendor.js:80243:9)
    at Vertices.walk (http://localhost:4200/assets/vendor.js:80157:12)
    at DAG.each (http://localhost:4200/assets/vendor.js:80087:22)
    at DAG.topsort (http://localhost:4200/assets/vendor.js:80095:12)
    at Class._runInitializer (http://localhost:4200/assets/vendor.js:61653:13)
    at Class.runInitializers (http://localhost:4200/assets/vendor.js:61625:12)
    at Class._bootSync (http://localhost:4200/assets/vendor.js:59923:14)
    at Class.boot (http://localhost:4200/assets/vendor.js:59890:14)


Source:     
Error: Cannot call `visit` without having first called `setupApplicationContext`.
    at visit (http://localhost:4200/assets/test-support.js:44177:13)
    at Object._callee$ (http://localhost:4200/assets/tests.js:23:47)
    at tryCatch (http://localhost:4200/assets/vendor.js:12365:40)
    at Generator.invoke [as _invoke] (http://localhost:4200/assets/vendor.js:12591:22)
    at Generator.prototype.<computed> [as next] (http://localhost:4200/assets/vendor.js:12417:21)
    at asyncGeneratorStep (http://localhost:4200/assets/tests.js:6:105)
    at _next (http://localhost:4200/assets/tests.js:8:196)
    at http://localhost:4200/assets/tests.js:8:366
    at new Promise (<anonymous>)
    at Object.<anonymous> (http://localhost:4200/assets/tests.js:8:99)

After a little digging, it looks like something is setting the test context incorrectly. It's just an empty object:

enter image description here

Thus, isApplicationTestContext(context) returns false and the second error gets thrown. I'm guessing the first error is thrown because the app has some initializers that perform lookups.

In an effort to add this acceptance test I also updated the test-helper.js file to the following:

import Application from "../app";
import config from "../config/environment";
import { setApplication } from "@ember/test-helpers";
import { start } from "ember-qunit";

setApplication(Application.create(config.APP));

start();

With the above file, all tests are failing so it seems that setApplication is causing the test context to be set incorrectly? The old test-helper.js file was like so:

import resolver from "./helpers/resolver";
import { setResolver } from "@ember/test-helpers";
import { start } from "ember-cli-qunit";

setResolver(resolver);
start();

I've tried re-adding the setResolver call but it doesn't make a difference. Has anyone else run into these issues with the new ember-qunit syntax or could maybe see what I'm doing wrong? Also, I've set autoboot = false; in the environment.js file which didn't make a difference. The test suite also has one or two tests that are still written in the older ember-qunit syntax. Any help would be appreciated!




Ember add customEvents

I'm using Ember 2.9 and would like to use the "paste" event.

How I can add paste as an customEvent on start up the application:

This is my current app.js:

import Ember from 'ember';
import Resolver from './resolver';
import loadInitializers from 'ember-load-initializers';
import config from './config/environment';

let App;

Ember.MODEL_FACTORY_INJECTIONS = true;

App = Ember.Application.extend({
  modulePrefix: config.modulePrefix,
  podModulePrefix: config.podModulePrefix,
  Resolver
});

loadInitializers(App, config.modulePrefix);

export default App;



mardi 1 octobre 2019

How can I add properties to a component in a unit test before init?

I'm working on an Ember component with an init function that I'd like to add a unit test for. The component has the following properties:

1) The init function must not be run more than once, and

2) The component depends on having a model (currentUser) passed to it.

So far I have tried writing a test like this:

test('#init', function(assert) {
  const component = this.owner.lookup('component:component-that-depends-on-property');

  const currentUser = make('user');
  component.set('currentUser', user);

  component.init();

  assert.ok(component.somethingHasHappened);
});

My problem is that init method is run on the owner.lookup line, meaning I have no way of getting the currentUser into the component before it runs. Again, I cannot run the init method more than once without blowing up the component's state.

I noticed that the lookup method takes an options argument and thought I might be able to use that to pass currentUser in, but that doesn't seem to work and I couldn't find much documentation on the lookup method.

I'd like to avoid writing an integration test for this, if possible. Is there a good way of doing this/workaround I'm not seeing?




How to go from a deployed ember project to local development project?

I'm using a deployed github repo project as a starting point for my own development project. Using ember-cli and ember serve I get a server running on localhost:4200. But it says

Proxying to https://xxxxx.yyy

where xxxxx.yyy is the website of the official deployed project, and the localhost:4200 server interacts with the deployed project's databases.

How do I tell ember to start a completely new local server that creates local empty databases, instead of proxying to the deployed website?




Ember.js ajax POST request not going through mirage

I am writing some tests for a component in my Ember application, where the component performs an ajax POST request to my servers API that will return a string of the location of a file.

I have added in the mirage/config.js file a route that should be used when the ajax request is performed.

  this.post('/foobar', () => {
    return "test";
  });

When I run my tests, I can see in the network tab and console that the ajax request is attempting to be performed on my localhost, but is getting a Connection Refused error.

POST http://localhost:8000/foobar net::ERR_CONNECTION_REFUSED.

When putting a debugger in the mirage/config.js file, it is not stopping there and it seems to be ignoring the route in my mirage/config.js entirely.

The URL and namespace are all set up in the config file.

What can I do to test further and find out why the request is not going through mirage?