0

How do I refactor ngOnChanges to reduce its Cognitive Complexity from the current 41 to the recommended 15? What I currently understand is reducing cognitive complexity is making it more readable to a new user. I tried certain things but I could not reach the threshold limit. I am not much familiar with Cognitive Complexity. Kindly help me through this. A detailed explanation would be appreciated.

ngOnChanges{
    this.dataset.data = this.chartData.data;
    this.labels = this.chartData.labels;
    this.legend = this.chartData.legend;
    this.chartStyle = this.chartData.chartStyle || {};

    if (this.chartData.hasOwnProperty("dataPresent")) {
        if (!this.chartData.dataPresent) {
            this.dataAbsent = true;
            this.chartStyle = {
                display: "none",
            }
        }
    }

    if (!this.chartData.hasOwnProperty("color")) {
        this.colors = [
            {
                backgroundColor: [
                    LEDSColorPalette.purple[500],
                    LEDSColorPalette.purple[50],
                ]
            }
        ]
    }
    else {
        this.colors = [this.chartData.color]
    }

    if (!this.chartData.hasOwnProperty("rotation")) {
        this.chartData.rotation = -90;
    }

    if (!this.chartData.hasOwnProperty("circumference")) {
        this.chartData.circumference = 360;
    }

    this.options = {
        rotation: this.chartData.rotation * (Math.PI / 180),
        responsiveAnimationDuration: 3000,
        maintainAspectRatio: false,
        circumference: this.chartData.circumference * (Math.PI / 180),
        responsive: true,
        tooltips: {
            enabled: this.chartData.tooltips || false,
        },
        animation:{
            duration: 3000,
        },
        legend: {
            position: this.chartData.legendPosition || "bottom",
            labels: {
                usePointStyle: true,
            }
        },
        title: {
            display: this.chartData.chartTitle,
            text: this.chartData.chartTitle,
            fontSize: this.chartData.chartTitleFontSize || 20,
            fontColor: this.chartData.chartTitleFontColor,
        },
        plugins: {
            dataLabels: this.chartData.dataLabels || false,
            doughnutlabel: false,
        },
        layout: this.chartData.layout || {},
        aspectRatio: this.chartData.aspectRatio || 3,
    }
    if (this.chartData.hasOwnProperty("cutoutPercentage")) {
        this.options.cutoutPercentage = this.chartData.cutoutPercentage;
    } else {
        this.options.cutoutPercentage = 90;
    }
    if (this.chartData.hasOwnProperty("tooltipsCallbacks")){
        this.options.tooltips.callbacks = {};
        Object.keys(this.chartData.tooltipsCallbacks).forEach((callback) => {
            this.options.tooltips.callbacks[callback] = new Function(
                this.chartData.tooltipsCallbacks[callback].arguments,
                this.chartData.tooltipsCallbacks[callback].body,
            )
        })
    }
    if (this.chartData.hasOwnProperty("centerText")){
        let centerText: any = [];

        if (isString(this.chartData.centerText)) {
            centerText = [{ text: this.chartdata.centerText }];
        } else if (isArray(this.chartData.centerText)){
            this.chartData.centerText.forEach((elem) => {
                if (isObject(elem)) {
                    centerText.push(elem);
                } else {
                    centerText.push({text: elem})
                }
            })
        } else if (isObject(this.chartData.centerText)){
            centerText = [this.chartData.centerText]
        }
        centerText.forEach((label, i) => {
            label.text = label.text + "";
            if(!label.hasOwnProperty("font")){
                label.font = {};
            }
            if(!label.font.hasOwnProperty("family")){
                label.font.family = '"Myriad Set Pro",Arial';
            }
            if(i === 0 && !label.font.hasOwnProperty("size")){
                label.font.size = "40";
            }
            if(i === 0 && !label.hasOwnProperty("color")){
                label.color = "#000";
            }
        }) 
        this.options.plugins.doughnutlabel = {
            labels: centerText,
        }
    }
}
  • I would recommend you to take a look at this [Answere](https://stackoverflow.com/questions/28049094/replacing-if-else-statement-with-pattern#:~:text=This%20is%20a%20classic%20Replace%20Condition%20dispatcher%20with%20Command%20in%20the%20Refactoring%20to%20Patterns%20book.) – Karan Sahu Oct 05 '22 at 20:59
  • 1. `if(A){if(B){...}}` (no else no break/return/system.exit in between;), can be "reduced" to `if(A&&B){...}` – xerx593 Oct 05 '22 at 21:12
  • 2. independent blocks (if, if/else..., for, while..) can be moved to "different methods" (but you only shift the problem to another "sonarcube metric") – xerx593 Oct 05 '22 at 21:13
  • maybe strategy pattern can help (https://www.dofactory.com/javascript/design-patterns/strategy) – FolabiAhn Oct 05 '22 at 21:52
  • You can simply move checking(this.chartData.hasOwnProperty("dataPresent") to isDataPresent(Params)) logic to their own method/function. It will reduce complexity and easy to read. Do it for all the logics – Hasan Khan Oct 06 '22 at 03:28

0 Answers0