How to manage infiniteScroll with ion-segment - ionic2

I am using the latest ionic 3.6.0.
I am having a problem with infiniteScroll and ion-segment when one of the segments reaching the end , where infiniteScroll.enable(false). Switching to another segment then, the infiniteScroll is not enabled at all… even if I put the boolean value in a variable and initialize it at constructor level.
.ts:
doInfinite(infiniteScroll){
if (this.segment === 'all'){
this.doInfiniteForSegmentAll(infiniteScroll);
} else
if (this.segment === 'featured'){
this.doInfiniteForSegmentFeatured(infiniteScroll);
}
}
doInfiniteForSegmentAll(infiniteScroll){
this.service.getAllData().subscribe(res => {
if (res.length > 0){
//Do stuff
} else {
infiniteScroll.enable(false)
//show a toast
}
});
}
doInfiniteForSegmentFeatured(infiniteScroll){
this.service.getFeaturedData().subscribe(res => {
if (res.length > 0){
//Do stuff
} else {
infiniteScroll.enable(false)
//show a toast
}
});
}
.html:
<ion-infinite-scroll *ngIf="segment === 'all' || segment === 'featured'" (ionInfinite)="doInfinite($event)" threshold="50px">
<ion-infinite-scroll-content
loadingText="Loading" loadingSpinner="dots"></ion-infinite-scroll-content>
</ion-infinite-scroll>

Ok , I think it seems that ion-infinite-scroll should be separate for each segment.. therefore:
.html:
<ion-infinite-scroll *ngIf="segment === 'all'" (ionInfinite)="doInfinite($event)" threshold="50px">
<ion-infinite-scroll-content
loadingText="Loading" loadingSpinner="dots"></ion-infinite-scroll-content>
</ion-infinite-scroll>
<ion-infinite-scroll *ngIf="segment === 'featured'" (ionInfinite)="doInfinite($event)" threshold="50px">
<ion-infinite-scroll-content
loadingText="Loading" loadingSpinner="dots"></ion-infinite-scroll-content>
</ion-infinite-scroll>
This is since I am not using ngSwitch and having only one kind of looped list for each segment.

Related

How can I write if-else conditions in cypress according to element's value?

How can I run this function, according to the value change of element with if-condition?
assertSwitch(){
cy.get('[data-test="form-switch"]').invoke('attr','value').then(($switchOnOff) =>{
if($switchOnOff == true){
cy.isContain('.item-undefined-switch[data-test="item-undefined-email"]', 'true')
}else{
cy.isContain('.item-undefined-switch[data-test="item-undefined-email"]', 'false')
}
})
}
You can do something like this:
cy.get('[data-test="form-switch"]').then(($ele) => {
if ($ele.attr('val') == 'true') {
cy.get('button[data-test="form-switch-input"]').should(
'have.attr',
'aria-checked',
'true'
)
//Add something here
} else {
cy.get('button[data-test="form-switch-input"]').should(
'have.attr',
'aria-checked',
'false'
)
//Add something here
}
})
The problem is both switches have the same data-test, so Cypress starts to get confused
cy.get('[data-test="form-switch"]')
.eq(0) // pick one
.invoke('attr','aria-checked') // this attr indicates checked state
.then(($switchOnOff) => {
if($switchOnOff === 'true') { // note adjustments here
cy.isContain('.item-undefined-switch[data-test="item-undefined-email"]', 'true')
} else {
cy.isContain('.item-undefined-switch[data-test="item-undefined-email"]', 'false')
}
})
Or all switches
cy.get('[data-test="form-switch"]')
.each(($switchOnOff) => {
const value = $switchOnOff.attr('aria-checked')
cy.isContain('.item-undefined-switch[data-test="item-undefined-email"]', value)
})

Write a mocha unit test code for the following meteor code

I want to know how to write test code using mocha for the meteor function
export const physicalToLogical = (physicalStatus, planningStartDate, planningEndDate) => {
if(physicalStatus === STATUS_PHYSICAL_CREATING) {
return STATUS_LOGICAL_CREATING;
} else if (physicalStatus === STATUS_PHYSICAL_OPEN) {
const now = new Date();
if(planningStartDate.getTime() <= now && planningEndDate.getTime() > now) {
return STATUS_LOGICAL_OPEN_FOR_PLAN;
} else if(planningStartDate.getTime() > now) {
return STATUS_LOGICAL_PROSPECT;
}
return STATUS_LOGICAL_REVIEW;
} else if (physicalStatus === STATUS_PHYSICAL_CLOSED) {
return STATUS_LOGICAL_CLOSED;
} else if (physicalStatus === STATUS_PHYSICAL_ARCHIVED) {
return STATUS_LOGICAL_ARCHIVED;
}
throw new Error("Not implemented yet");
};
First, this function has nothing to do with Meteor.
Writing tests for such a function would involve sending different statuses to the method and expecting the different results.
Here's an example (using chai as the assertions library) :
describe('physicalToLogical', () => {
it('should return the given status', () => {
expect(physicalToLogical(STATUS_PHYSICAL_CREATING, null, null)).
toEqual(STATUS_LOGICAL_CREATING);
});
it('should...', () => {
...
});
...
});
This is one of the many simple cases you have to write for that code.
Several other tests need to be written for the cases involving dates, but the format is more or less the same.

Ember: Setting a component object value within a promise

I have component with a couple of properties, using a promise in the willRender hook to try and create a (pagination) object:
export default Ember.Component.extend({
pagination:null,
testing:null, // to check if this.set is ok within the promise!
willRender() {
let page = {};
let model = this.get('data');
model.get('products').then(relatedItems => {
let maxRecords = relatedItems.get('length');
relatedItems.forEach(function(item,index) {
if (item.get('slug') === itemModel.get('id')) {
if (index === 0) {
page.Prev = null;
page.Next = relatedItems.objectAt(index+1).get('slug');
}
else if (index+1 === maxRecords) {
page.Prev = relatedItems.objectAt(index-1).get('slug');
page.Next = null;
}
else {
page.Prev = relatedItems.objectAt(index-1).get('slug');
page.Next = relatedItems.objectAt(index+1).get('slug');
}
}
});
this.set('testing','hello world');
console.log(this.get('testing')); // hello world
this.set('pagination',page);
console.log(this.get('pagination')); // Object {Prev: "product-1", Next: "product-2"}
},reject => {
console.log('error '+reject);
});
}
})
In my template
{{testing}} // prints hello world
However, if I try and access {{pagination}} eg {{log pagination}}, the browser crashes with a loop printing out the object to the console.
I don't know where I'm going wrong here - any help much appreciated!
It's likely you are triggering the template to rerender causing willRender to fire over and over which causes an infinite loop in your code.
willRender is a non-standard place to do this code, init would be more standard since it only fires on initialization of the component. Even better would be to use
myInit: Ember.on('init', function(){
....
})`
instead of overriding willRender on the object.
try to check whether Object is present at specific position. i think its going undefined during iteration of for loop. try to ensure that ObjectAt is not returning undefined or null value during running of for loop.
relatedItems.forEach(function(item,index) {
if (item.get('slug') === itemModel.get('id')) {
if (index === 0) {
page.Prev = null;
if(relatedItems.objectAt(index+1) ! = undefined) {
page.Next = relatedItems.objectAt(index+1).get('slug');
}else{
page.Next == null;
}
}
else if (index+1 === maxRecords) {
if(relatedItems.objectAt(index-1) ! = undefined) {
page.Prev = relatedItems.objectAt(index-1).get('slug');
}else{
page.Prev = null;
}
page.Next = null;
}
else {
if(relatedItems.objectAt(index-1) ! = undefined) {
page.Prev = relatedItems.objectAt(index-1).get('slug');
}else{
page.Prev = null;
}
if(relatedItems.objectAt(index+1) ! = undefined) {
page.Next = relatedItems.objectAt(index+1).get('slug');
}else{
page.Next = null;
}
}
}
Please ensure that Object at is returning object.
There seems to be a few problems here, would be interested to know what your console errors are.
You don't seem to have defined itemModel so don't know how you're referencing that.
Also you can't access this from within a .then. You need to do something like this to set a component variable.
var _this = this;
promise().then(function(results) {
_this.set('testing', 'hello world');
});
you are not using , after testing:null
there should be , after testing property like that
pagination:null,
testing:null, // i use ',' after testing: null property
try to use your pagination code under init hook rather than willrender hook
init() {
//you code
},

Directive to allow decimal numbers with only 1 decimal point

I have an angular application where an input field should allow only positive numbers with one decimal point. In my directive I am replacing anything other than 0-9 and '.'.But currently my application is accepting multiple decimal values.
It should accept:
0.5
0.56
Not
0.5.5 or 0..5
PFB the code:
link: function (scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function (inputValue) {
// this next if is necessary for when using ng-required on your input.
// In such cases, when a letter is typed first, this parser will be called
// again, and the 2nd time, the value will be undefined
if (inputValue === undefined) {
return '';
}
var transformedInput = inputValue.replace(/[^0-9\.]/g, '');
if (transformedInput !== inputValue) {
modelCtrl.$setViewValue(transformedInput);
modelCtrl.$render();
}
return transformedInput;
});
}
This question might seem ignorant but I have tried all the solutions provided before this but changing my regular expression according to the same doesn't seem to work. It accepts right now multiple '.'.
Thanks in advance.
Here is fiddle http://jsfiddle.net/oora0t93/ check it:-
app.directive('inputPrice', function () {
return {
restrict: 'EA',
template: '<input name="{{inputName}}" ng-model="inputValue" />',
scope: {
inputValue: '=',
inputName: '='
},
link: function (scope) {
scope.$watch('inputValue', function(newValue,oldValue) {
if(String(newValue).indexOf(',') != -1)
scope.inputValue = String(newValue).replace(',', '.');
else {
var index_dot,
arr = String(newValue).split("");
if (arr.length === 0) return;
if (arr.length === 1 && (arr[0] == '-' || arr[0] === '.')) return;
if (arr.length === 2 && newValue === '-.') return;
if (isNaN(newValue) || ((index_dot = String(newValue).indexOf('.')) != -1 && String(newValue).length - index_dot > 3 )) {
scope.inputValue = oldValue;
}
}
});
}
};
});
I got it. I did not find a regular expression solution so did it using some javascript string manipulations. PFB the code:
var firstIndexOfDecimal = transformedInput.indexOf('.');
var lastIndexofDecimal = transformedInput.lastIndexOf(".");
if(firstIndexOfDecimal !== lastIndexofDecimal){
transformedInput = transformedInput.substr(0,lastIndexofDecimal) + transformedInput.substr(lastIndexofDecimal+1, transformedInput.length);
}
Thanks for the help.

cannot call method 'set' of undefined ember

I get cannot call method 'set' of undefined object when I remove item from ArrayController.
start: function () {
this.registerModel('listController', Ember.ArrayController.create());
this._super();
},
My view looks like,
{{#each item in marketingListCriteriaList}}
{{view Select valueBinding="item.entity" contentBinding="controller.allEntities" optionLabelPath="content.Name" optionValuePath="content.Name" }}
{{/each}}
I have a observer method which observes
.observes('listController.#each.entity')
The above observer gets called when i remove object from array controller using removeObject() method.
Are there any other ways to remove objects from array?
entityChangeObserver: function (thisModule) {
var thisModule = this;
var criteria = thisModule.get('listController.content');
if (criteria != undefined && criteria.length > 0 && criteria[criteria.length - 1].entity != undefined) {
var presentObject = criteria[criteria.length - 1];
$.each(thisModule.get('allEntities'), function (index, item) {
if (presentObject.entity === item.Name) {
presentObject.set('allAttributes', item.Attributes);
}
});
}
}.observes('listController.#each.entity'),
attributeChangeObserver: function (thisModule) {
var thisModule = this;
var criteria = thisModule.get('listController.content');
if (criteria != undefined && criteria.length > 0 && criteria[criteria.length - 1].attribute != undefined) {
var presentObject = criteria[criteria.length - 1];
$.each(presentObject.get('allAttributes'), function (index, item) {
if (presentObject.attribute === item.Name) {
thisModule.setDefaulsVisibility(presentObject);
if (item.Type === '1') {
presentObject.set('textVisible', true);
}
else if (item.Type === '2') {
presentObject.set('selectVisible', true);
presentObject.set('allValues', item.Values);
}
else if (item.Type === '3') {
presentObject.set('multiSelectVisible', true);
presentObject.set('allValues', item.Values);
}
else if (item.Type === '4') {
presentObject.set('dateVisible', true);
}
}
});
}
}.observes('listController.#each.attribute'),
You can also remove array elements using "remove" instead of "removeObject" however, you might want to double check your logic in your observer which gives undefined error when you remove an object. I would recommend sticking to remove object and just fixing the error within the observer. Also, do note that using "remove" will not instantly update handlebar templates if you are looping over the array.
Firstly sorry for the late post.
I figured the solution for the problem "calling set on destroyed object".
In my control definition of didInsertElement I made a check for if (!me.isDestroyed) for every set operation.