javascriptangularjsobjectpropertiesnested-properties

Clean way to acces nested variable properties from the $scope


I want to access same variable properties in a java script file but because are too many properties the code looks a bit to ugly. I have the next code:

$scope.invoice = new Invoice();

$scope.operations = {
    editingLine: {},
    isNewLine: false,
    isEditOpen: false
};

$scope.modify = function (invoiceLine) {

    if ($scope.operations.isEditOpen) return;

    let originalLine = $scope.invoice.invoiceLines.find(line => line.id = invoiceLine.id);
    tempLine = angular.copy(originalLine);
    $scope.operations.editingLine[invoiceLine.id] = true;
    $scope.operations.isEditOpen = true;
};

Is there any way to access the the property invoiceLine which is set on the object invoice, or the property isEditOpen which is set on the object operations in cleaner way? I have a lot of repetition of this code in my file and I want to find a clener way to access properties like this.

I know that I can to define a variable var operations = $scope.operations and to access the property operations.isEditOpen when I need this value but still, I want something more simpler because I don't want to create variable for all objects from the scope.

Is there any way to create a function with two params (objectFromScope, neededProperty) that can return the requiered property value from a variable which is set on the scope? Or is there any better way to do not have such much code when I want to access an object property from the scope?

PS: I can also do something like this:

let editingLine = $scope.operations.editingLine;
    let isNewLine = $scope.operations.isNewLine;
    let isEditOpen = $scope.operations.isEditOpen;

$scope.modify = function (invoiceLine) {

        if (isEditOpen) return;

        let originalLine = invoiceLines.find(line => line.id = invoiceLine.id);
        tempLine = angular.copy(originalLine);
        editingLine[invoiceLine.id] = true;
        isEditOpen = true;
    };

But is this a good approach?


Solution

  • Is there any way to create a function with two params ( objectFromScope, neededProperty ) that can return the required property value from a variable which is set on the scope? Or is there any better way to do not have such much code when I want to access an object property from the scope?

    Yes, but I don't see how it saves you any trouble. It will also make it harder to switch to TypeScript (though you can make it work with keyof if you don't want to dereference an entire property path).

    But this is that function:

    function getPropertyValue( objectFromScope, neededProperty ) {
        
        const pathComponents = neededProperty.split( '.' );
        
        let obj = objectFromScope;
        for( const component of pathComponents ) {
            obj = obj[ component ];
        }
    
        return obj;
    }
    

    Usage:

    $scope.invoice = new Invoice();
    
    $scope.operations = {
        editingLine: {},
        isNewLine: false,
        isEditOpen: false
    };
    
    $scope.modify = function( invoiceLine ) {
    
        if ($scope.operations.isEditOpen) return;
    
        const lines = getPropertyValue( $scope, 'invoice.invoiceLines' );
        let originalLine = lines.find(line => line.id = invoiceLine.id);
    
        tempLine = angular.copy(originalLine);
        $scope.operations.editingLine[invoiceLine.id] = true;
        $scope.operations.isEditOpen = true;
    };
    

    ...but this really doesn't make your code any easier to read or maintain. Instead it makes it worse because doing things this way is very non-idiomatic for JavaScript and AngularJS: anyone else who works on this project will stare at the code for a few minutes and scratch their head before wondering out loud why you're doing this in the first place.