0

I need to achieve the same output but as you see the length of the ID's array is zero because I cannot achieve this output using push command, it generates errors like:

push is not a function

Cannot use indexOf for undefined or false

I need to solve this array with a push command and make the output exactly like below but I cannot use the each function because the length is zero.

var RepeaterClass = {
    Repeaters: [],
    collectRepeaterValues: function (rep_id, cat_id, element_id) {
        this.Repeaters[rep_id] = this.Repeaters[rep_id] || [];
        this.Repeaters[rep_id][cat_id] = this.Repeaters[rep_id][cat_id] || [];

        if (-1 === this.Repeaters[rep_id][cat_id].indexOf(element_id)) {
            this.Repeaters[rep_id][cat_id].push(element_id);
        }
    },
};

Implementing of this code:

ID_1: Array(0)
   category: Array(1)
      0: "dog"
      
   animals: Array(2)
      0: "dog"
      1: "cat"
Daweed
  • 1,419
  • 1
  • 9
  • 24
Hady Shaltout
  • 606
  • 1
  • 9
  • 22
  • What's the input and expected output? – Ramesh Reddy Feb 07 '21 at 14:29
  • 1
    This is not valid JavaScript code. The `var Repeaters = [];` isn't valid where it is. What's the actual code? – Felix Kling Feb 07 '21 at 14:31
  • The actual code is very large and complicated scenario, in short the function collectRepeaterValues will be triggered for each slide added in that repeater and will collect some elements from it after certain checks. This function's output return the array at the end but the array length is zero, The using of push is not working – Hady Shaltout Feb 07 '21 at 14:41

2 Answers2

0

As others have commented it's not entirely clear what you're asking here. This code sort of works if you fix the line var Repeaters =[];

I think the confusion is arising because we create Repeaters as an array, but then I think you must be calling collectRepeaterValues with strings for rep_id and cat_id (e.g. 'ID_1' and 'animals') to get the output you are showing. It should be called with numbers if you want to create arrays. You can't access an array element with a string.

If you call with strings JavaScript is going to create object properties on the array when you do Repeaters[rep_id] = Repeaters[rep_id] || []. That is to say, if we execute the statement Repeaters['ID_1'] = [] in JavaScript it's not doing array assignment even if Repeaters is an array. It will create an object property called ID_1 and makes its value the empty array.

The snippets below show calling the (corrected) object with numbers and with strings and the results.

As an aside, the if statement in collectRepeaterValues is not working.

Now we're back on what the question really is. Do you want arrays, which have to be indexed by numbers of course, or do you want objects with string properties?

// CALLING WITH STRINGS
var RepeaterClass = {
    Repeaters: [], // Fixed so it's an object property
    collectRepeaterValues: function (rep_id, cat_id, element_id) {

        this.Repeaters[rep_id] = this.Repeaters[rep_id] || [];
        this.Repeaters[rep_id][cat_id] = this.Repeaters[rep_id][cat_id] || [];

        if (-1 === this.Repeaters[rep_id][cat_id].indexOf(element_id)) {
            this.Repeaters[rep_id][cat_id].push(element_id);
        }
    }
}

// What I think you're doing?
RepeaterClass.collectRepeaterValues("ID_1", "category", "dog");
RepeaterClass.collectRepeaterValues("ID_1", "animals", "dog");
RepeaterClass.collectRepeaterValues("ID_1", "animals", "cat");

// At the top level RepeaterClass.Repeaters is an empty array with a 'ID_1' property
// Array length is zero...
console.log(RepeaterClass.Repeaters.length);  // 0
// But we have a property ID_1, that is itself an array of zero length with category
// and animals properties that are arrays
console.log(RepeaterClass.Repeaters.ID_1.category[0]);    // dog
console.log(RepeaterClass.Repeaters.ID_1.animals[0]);     // dog
console.log(RepeaterClass.Repeaters.ID_1.animals[1]);     // cat
// Note that this IS the result at the end of the question

// EDIT: You can iterate over the properties with for..in
console.log('Iterating categories on ID_1:');
for (var cat_id in RepeaterClass.Repeaters.ID_1) {
    console.log(cat_id);
}

// CALLING WITH NUMBERS
var RepeaterClass = {
    Repeaters: [], // Fixed so it's an object property
    collectRepeaterValues: function (rep_id, cat_id, element_id) {

        this.Repeaters[rep_id] = this.Repeaters[rep_id] || [];
        this.Repeaters[rep_id][cat_id] = this.Repeaters[rep_id][cat_id] || [];

        if (-1 === this.Repeaters[rep_id][cat_id].indexOf(element_id)) {
            this.Repeaters[rep_id][cat_id].push(element_id);
        }
    }
}

// How this code is meant to be called I think
RepeaterClass.collectRepeaterValues(0, 0, "dog");
RepeaterClass.collectRepeaterValues(0, 1, "dog");
RepeaterClass.collectRepeaterValues(0, 1, "cat");

// At the top level RepeaterClass.Repeaters is now an array structure
console.log(RepeaterClass.Repeaters.length);  // 1
console.log(RepeaterClass.Repeaters[0][0][0]); // dog
console.log(RepeaterClass.Repeaters[0][1][0]); // dog
console.log(RepeaterClass.Repeaters[0][1][1]); // cat
Rich N
  • 8,939
  • 3
  • 26
  • 33
  • It's very complicated than this, We need to use each but the length is always zero, We won't call index numbers. Thanks for your help and time – Hady Shaltout Feb 07 '21 at 16:21
  • If you want to iterate using strings you can use for..in to iterate the object properties. I'll edit the code to show that. Just to be clear, you [can't index an array with strings](https://stackoverflow.com/a/9526896/4166522) in JavaScript. So if you're not using index numbers the array length is going to be zero. – Rich N Feb 07 '21 at 16:26
0

The Only Solution I found is by create another array to store the elements inside the repeater then push it in the main Repeaters array outside the funtion

But Still cannot achieve it in the same function.

var RepeaterClass = {
    
    Repeaters: {},
    validated: {},

    collectRepeaterValues: function( cat_id, element_id ) {
            
        // this.Repeaters[ rep_id ]    = this.Repeaters[ rep_id ] || [];
        this.validated[ cat_id ] = this.validated[ cat_id ] || [];

        if ( -1 === this.validated[ cat_id ].indexOf( element_id ) ) {
            
            this.validated[ cat_id ].push( element_id );
                
        }

    }


    AnotherFunction: function() {

        _.each( REP, function( repDetails, repID ) {

            _.each( repDetails, function( value ) {
                /* 1. Call the Collector */
                collectRepeaterValues( value['cat'], value['id'] );

            } );

            /* 2. push the validated output inside the main array */
            this.Repeaters[ repID ] = this.Repeaters[ repID ] || [];
            this.Repeaters[ repID ] = this.validated;
            
            /* Empty for another session */
            this.validated = {};

        } );


    }

}
Hady Shaltout
  • 606
  • 1
  • 9
  • 22