Emberjs link-to href test in integration component - javascript

I'm trying to test a link-to href property in an ember component. with ember 2.0
but when I render the component with renter hbs it renders this:
<div id=\"23\" class=\"ember-view\">
<p><!----></p>
<div class=\"participantes\">
<a id=\"ember282\" class=\"ember-view\">
<span>rnt-ayl-bld-js-jvr-frd-edw</span>
</a>
</div>
and the href property is not rendered,
I read that is something related to router but I'm not sure how to include the router in the test I tried something like:
moduleForComponent('conversation-item', 'Integration | Component | conversation item', {
integration: true,
setup(){
const router = this.lookup('router:main');
router.startRouting(true);
}
});
but the lookup function is not present
TypeError: 'undefined' is not a function (evaluating
'container.lookup('router:main')')

You might want to take a look at this question Ember Component Integration Tests: `link-to` href empty
Although it is 1.13 it might help you. Unfortunately I'm using ember-mocha and am still having problems.
Essentially, you're really close, you just need to use the container to look up the router.
// tests/helpers/setup-router.js
export default function({ container }) {
const router = container.lookup('router:main');
router.startRouting(true);
}
// tests/integration/components/my-component-test.js
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import setupRouter from '../../helpers/setup-router';
moduleForComponent('my-component', 'Integration | Component | my component', {
integration: true,
setup() {
setupRouter(this);
}
});

Related

Multiple components, but only first one rendered

I'm trying to create simple ToDo app using Ractive.js and Redux, but I ran into a problem with rendering more than one component on my page.
Javascript code:
import Ractive from 'ractive';
import template from './Home.html';
import './Home.less';
import { AddToDoForm, ToDoList } from '../';
export default Ractive.extend({
template,
data: {
message: 'This is the home page.',
},
components: {
AddToDoForm,
ToDoList
}
});
HTML of the component:
<AddToDoForm store={{store}} />
<ToDoList store={{store}} />
But only the first component is rendered. The store parameter I'm passing is the Redux store, but it doesn't work even without it.
I would add to verify defaults as a
...
components:{
AddToDoForm: AddToDoForm,
ToDoList: ToDoList
}
...
syntax examples (answer/31096635)

Ember "Action passed is null or undefined in (action)" error

I have an Ember component checkout-form that contains some logic for handling a checkout process. Here’s a simplified version of how I’m using it:
{{#checkout-form}}
{{#each model.courses.otherDates as |date|}}
{{course-date model=date selectDate=(action selectDate) }}
{{/each}}
{{/checkout-form}}
Inside of my checkout-form.js component I have the following action:
selectDate(day) {
this.set("startAt", day.get("serverString"))
}
And finally inside of my course-date.js component I have:
click () {
const courseStart = this.get('courseStart')
this.get('selectDate')(courseStart)
}
However, when running this code I get the error:
ember.debug.js:19818 Assertion Failed: Action passed is null or undefined in (action) from <site#controller:checkout/date::ember389>.
What am I missing here? I am passing the action into the course-date component and not sure why is it asking for a controller?
Reason for the error is,
You are accessing selectDate which is undefined in that scope(ie., controller) If you do {{log 'selectDate value is ' selectDate}} inside that checkout-form which will print selectDate value is undefined. so if you want to access any properties, actions which are defined in the component then that component should yield those values.
Here is twiddle which demonstrates how you can yield action from component.
application.hbs
{{#checkout-form as |selectDate| }}
{{!--
here context is controller not the checkout-form component
Whatever you want to access from component, then component should yield those values.
--}}
{{course-date selectDate=(action 'selectDateInController')}}
{{course-date selectDate=selectDate}}
{{/checkout-form}}
application.js
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Ember Twiddle',
actions:{
selectDateInController(){
console.log(' selectDate in controller');
}
}
});
templates/components/checkout-form.hbs - Here we are yielding selectDate action
{{yield (action 'selectDate')}}
components/checkout-form.js
import Ember from 'ember';
export default Ember.Component.extend({
actions:{
selectDate(){
console.log(' selectDate in checkout-form component');
}
}
});
course-date.hbs - Here we are just using the closure action that is passed to this component.
<button {{action selectDate}}> CourseDate </button>

Vue how to call filter from parent

How can I be able to call filter of parent using single file component. Below are my code.
app.js
import computed from '../vue/mixins/computed.js';
import filters from '../vue/mixins/filters.js';
import methods from '../vue/mixins/methods.js';
const app = new Vue({
el: '#app',
mixins:[
computed,
filters,
methods
],
mounted: function() {
}
});
home.vue
<template>
<div class="home-content">
<h3>{{home | uppercase}}</h3>
</div>
</template>
<script type="text/javascript">
export default {
data: function() {
return {
home: 'home'
}
},
mounted: function() {
this.$parent.$options.methods.makeConsole();
}
}
</script>
It's giving me this warning in console "Failed to resolve filter: uppercase"
You should just make the filter global available before starting the root instance with
Vue.filter('uppercase', uppercase);
Where uppercase can be a simple function like
function uppercase(str)
return str.uppercase();
}
That would be the most simple and reliable way to use the filter on all vue components;
If you import your filters to your parent via mixins why don't you use that mixin in the child?
Please do not use the this.$parent-method as it makes your child component statical dependend of that parent.
To use the $parent approach you may need to declare the filter function from the parent as a filter in the child:
filters:{
uppercase: this.$parent.$options.filters.uppercase
}
There is no point. Just include your mixin in the child as well. A component should ideally be autonomous, and not aware of where it is in the hierarchy of components (at least not the ones above or on the same level.

Ember JS - Update property on all instances of a component

Is it possible to update a property on all instances of a component?
If I have 10 instances of the component below on a page, I would like to set the currentTrack property to false on all of them. Is this possible? Can it be done from inside one of the components?
import Ember from 'ember';
export default Ember.Component.extend({
currentTrack: true,
});
I'm using Ember 2.12
You can use Ember.Evented for this use case.
Here, there is a simple twiddle for it.
template.hbs
{{your-component-name currentTrack=currentTrack}}
{{your-component-name currentTrack=currentTrack}}
{{your-component-name currentTrack=currentTrack}}
// btn for disabling
<a href="#" class="btn" onclick={{action 'makeAllcurrentTracksFalse'}}>To false</a>
controller.js
currentTrack: true,
actions: {
makeAllcurrentTracksFalse() {this.set('currentTrack', false)}
}
or in your-component-name.js - you can use the same action as above and it will be applied to all components
How about you create entries for what ever thing your're trying to achieve.
const SongEntry = Ember.Object.extend({
});
To create an entry you would call (probably add a song to playlist?)
songs: [],
addNewSongToList: function(songName) {
const newEntry = MyMusicEntry.create({
isCurrent: false,
title: songName
});
this.get('songs').pushObject(newEntry);
},
activateNewSong: function(newSongToActivate) {
this.get('songs').forEach(s => s.set('isCurrent', false);
newSongToActivate.set('isCurrent', true)
}
Template would look like this
{{each songs as |song|}}
{{my-song-component songEntry=song changeSong=(action "activateNewSong")}}
{{/each}}
//my-song-component.js
<div class="song-layout" {{action "changeSong" song}}>

Writing Ember.js component Integration Tests with sub components

I am attempting to follow Alisdar's new Itegration tests instead of doing unit testing on my ember component.
I really like the new approach, but I have a problem when testing components which calls another component in its' view.
alpha component:
App.TestAlphaComponent = Ember.Component.extend({
listWords: []
});
alpha component view uses beta component:
{{#each listNumbers as num}}
{{test-beta word=num}}
{{/each}}
beta component:
App.TestBetaComponent = Ember.Component.extend({
word: 'hello world'
});
beta component view:
<h1>{{ word }} </h2>
Mocha Chai Integration test for TestAlphaComponent
import Ember from 'ember';
import { expect } from 'chai';
import {
describeComponent,
it
} from 'ember-mocha';
import hbs from 'htmlbars-inline-precompile';
import tHelper from "ember-i18n/helper";
import testBeta from "app/components/test-beta";
var foo;
describeComponent(
'test-alpha',
'Integration: testAlphaComponent',
{
integration: true
},
function() {
beforeEach(function () {
this.container.lookup('service:i18n').set('locale', 'en');
this.registry.register('helper:t', tHelper);
this.registry.register(
'component:test-beta',
testBeta
);
Ember.run(this, 'set','foo', ['foo','bar','baz']);
this.render(hbs`{{test-alpha listWords=foo}}`);
});
it('prints foo bar baz in h1s', function() {
expect($('h1').to.have.length(3);
});
});
);
my test fails. testBeta is never called, nor does it complain about missing components. What is the correct way to inject testBetaComponent into testAlpha's integration test environment?
Components need to have a dash in their names. Once you add a dash, subcomponents will be added automatically. See the note:
http://guides.emberjs.com/v1.13.0/components/defining-a-component/

Categories