Skip to content

Issue saying Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '50'. Current value: '50' #34306

@neofuture

Description

@neofuture

Can see a reason for this or a way to correct It

component html

<div class="slider"
     [ngClass]="[class, direction]"
     (mousedown)="dragStart($event)"
     #sliderElementTemplate
>
  <div class="sliderTrack {{ class }}"></div>
  <div class="sliderThumb {{ class }} noTransition">{{ val }}</div>
  <input type="hidden" name="{{ input }}]" id="{{ input }}" value="{{ val }}">
</div>

TS

import {AfterViewInit, Component, Input, OnInit, ViewChild} from '@angular/core';

@Component({
  selector: 'app-slider',
  templateUrl: './slider.component.html',
  styleUrls: ['./slider.component.css']
})
export class SliderComponent implements OnInit, AfterViewInit {
  private xOffset: any;
  private yOffset: any;

  @Input() min;
  @Input() max;
  @Input() val;
  @Input() input;
  @Input() steps;
  @Input() callBack;
  @Input() direction;
  @Input() inverted;
  @Input() class;

  @ViewChild('sliderElementTemplate') sliderElement;

  private dragging: boolean;
  private sliderTrack: any;
  private sliderThumb: any;

  constructor() {
  }

  ngOnInit() {
  }

  ngAfterViewInit() {
    this.sliderElement = this.sliderElement.nativeElement;
    this.sliderTrack = this.sliderElement.childNodes[0];
    this.sliderThumb = this.sliderElement.childNodes[1];
    this.setThumbPos();
  }

  setThumbPos() {
    this.sliderThumb.classList.add('noTransition');
    const range = this.max - this.min;
    const correctedStartValue = this.val - this.min;
    let percent = (correctedStartValue * 100) / range;

    if (this.inverted) {
      percent = 100 - percent;
    }

    if (this.direction === 'vertical') {
      this.sliderThumb.style.top = 'calc(' + percent + '% - ' + (this.sliderThumb.offsetHeight / 100 * percent) + 'px)';
    } else {
      this.sliderThumb.style.left = 'calc(' + percent + '% - ' + (this.sliderThumb.offsetWidth / 100 * percent) + 'px)';
    }
    const points = this.precision(this.steps);

    this.val = (Math.floor(this.val / this.steps) * this.steps).toFixed(points);

    this.sliderThumb.innerHTML = this.val;
    setTimeout(() => {
      this.sliderThumb.classList.remove('noTransition');
    }, 300);
  }

  dragStart(event) {
    this.xOffset = this.sliderElement.offsetLeft;
    this.yOffset = this.sliderElement.offsetTop;
    this.sliderThumb.classList.add('noTransition');
    if (event.target.className.indexOf('sliderTrack') !== -1) {
      this.sliderThumb.classList.remove('noTransition');
      this.dragging = true;
      this.dragGo(event);
    }
    this.dragging = true;

    // tslint:disable-next-line:no-shadowed-variable
    document.addEventListener('mousemove', (event) => {
      this.dragGo(event);
    });
    // tslint:disable-next-line:no-shadowed-variable
    document.addEventListener('mouseup', (event) => {
      this.dragStop(event);
    });

  }

  dragGo(event) {
    if (this.dragging) {

      let x = event.x || event.pageX;
      let y = event.y || event.pageY;

      x = x - (this.sliderThumb.offsetWidth / 2);
      y = y - (this.sliderThumb.offsetHeight / 2);

      if (x - this.xOffset < 0) {
        x = 0;
      }
      if (y - this.yOffset < 0) {
        y = 0;
      }

      if (x - this.xOffset > this.sliderElement.offsetWidth - this.sliderThumb.offsetWidth) {
        x = this.xOffset + this.sliderElement.offsetWidth - this.sliderThumb.offsetWidth;
      }

      if (y - this.yOffset > this.sliderElement.offsetHeight - this.sliderThumb.offsetHeight) {
        y = this.yOffset + this.sliderElement.offsetHeight - this.sliderThumb.offsetHeight;
      }

      if (this.direction === 'vertical') {
        const percent = (y - this.yOffset) / (this.sliderElement.offsetHeight - this.sliderThumb.offsetHeight) * 100;

        const val = (percent * (this.max - this.min) / 100) + this.min;

        const points = this.precision(this.steps);
        if (this.inverted === true) {
          this.val = ((this.max + this.min) - (Math.floor(val / this.steps) * this.steps)).toFixed(points);
        } else {
          this.val = (Math.floor(val / this.steps) * this.steps).toFixed(points);
        }

        this.sliderThumb.style.top = 'calc(' + percent + '% - ' + (this.sliderThumb.offsetHeight / 100 * percent) + 'px)';
      } else {
        const percent = (x - this.xOffset) / (this.sliderElement.offsetWidth - this.sliderThumb.offsetWidth) * 100;

        const val = (percent * (this.max - this.min) / 100) + this.min;

        const points = this.precision(this.steps);
        if (this.inverted === true) {
          this.val = ((this.max + this.min) - (Math.floor(val / this.steps) * this.steps)).toFixed(points);
        } else {
          this.val = (Math.floor(val / this.steps) * this.steps).toFixed(points);
        }

        this.sliderThumb.style.left = 'calc(' + percent + '% - ' + (this.sliderThumb.offsetWidth / 100 * percent) + 'px)';
      }

      this.sliderThumb.innerHTML = this.val;
    }
  }

  dragStop(event) {
    this.dragging = false;
  }

  precision(a) {
    if (!isFinite(a)) {
      return 0;
    }
    let e = 1;
    let p = 0;
    while (Math.round(a * e) / e !== a) {
      e *= 10;
      p++;
    }
    return p;
  }
}
Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '50'. Current value: '50'.
throwErrorIfNoChangesMode — core.js:8290
bindingUpdated — core.js:21606
interpolation1 — core.js:21738
ɵɵtextInterpolate1 — core.js:25007
ɵɵtextInterpolate — core.js:24978
SliderComponent_Template — slider.component.html:7
executeTemplate — core.js:13942
refreshView — core.js:13801
refreshComponent — core.js:15166
refreshChildComponents — core.js:13535
refreshView — core.js:13855
refreshComponent — core.js:15166
refreshChildComponents — core.js:13535
refreshView — core.js:13855
refreshComponent — core.js:15166
refreshChildComponents — core.js:13535
refreshView — core.js:13855
renderComponentOrTemplate — core.js:13916
tickRootContext — core.js:15330
detectChangesInRootView — core.js:15365
checkNoChangesInRootView — core.js:15395
checkNoChanges — core.js:16958
tick — core.js:42792
_loadComponent — core.js:42838
bootstrap — core.js:42764
forEach
_moduleDoBootstrap — core.js:42352
(anonymous function) — core.js:42307
onInvoke — core.js:41362
run — zone-evergreen.js:124
(anonymous function) — zone-evergreen.js:851
onInvokeTask — core.js:41340
runTask — zone-evergreen.js:168
drainMicroTaskQueue — zone-evergreen.js:570
promiseReactionJob

version

Angular: 9.0.0-rc.4
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router, service-worker
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.900.0-rc.4
@angular-devkit/build-angular     0.900.0-rc.4
@angular-devkit/build-optimizer   0.900.0-rc.4
@angular-devkit/build-webpack     0.900.0-rc.4
@angular-devkit/core              9.0.0-rc.4
@angular-devkit/schematics        9.0.0-rc.4
@angular/cdk                      8.2.3
@angular/pwa                      0.803.19
@ngtools/webpack                  9.0.0-rc.4
@schematics/angular               9.0.0-rc.4
@schematics/update                0.900.0-rc.4
rxjs                              6.5.3
typescript                        3.6.4
webpack                           4.41.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions