0

Trying to push each new created object into an array so that I am able to use these values elsewhere, however, after the loop runs, the entire array is filled by the first object that is created, and stuck for ideas, ive tried mapping, for loops and similar, but the issue persists.

whilst the objects created are all different, when the loop has finished it hasn't.

const callEvents = getAllCallEvents(skypeConversation)
            let callInformationArray = []
            callEvents.forEach(call => {
                let callObject = createCallInformationObject(call, callInfo)
                if (callObject) {
                    // /console.log(callObject)
                    callInformationArray.push(callObject)

                }
            })

Object being created

let callInfo = {
    whoStartedCall: false,
    participentOne: false,
    participentTwo: false,
    duration: false,
    timeStarted: false,
    timeEnded: false,
    callId: false,
    callDate: false,
    callType: false,
}

The closest i can think of is that perhaps the object created for each part of the loop, whilst created, the first one isn't destroyed, though I couldn't think that would be possible as callObject when logged in the console is different each time. Taken a look at this page and attempted the stuff in here, but same issue persists

here's the entire file if needed (getting this working first before refactoring)

/**
 * Declaring Objects
 */
let callInfo = {
    whoStartedCall: false,
    participentOne: false,
    participentTwo: false,
    duration: false,
    timeStarted: false,
    timeEnded: false,
    callId: false,
    callDate: false,
    callType: false,
}
//DURATION IS IN SECONDS

window.addEventListener('load', function () {
    document.getElementById('tar-upload-input').addEventListener('change',function (e) {

        let reader = new FileReader();
        reader.onload = function(event) {
            let skypeJsonObject = JSON.parse(event.target.result),
                skypeConversation = skypeJsonObject.conversations

            // Get all the events that are calls, discard the rest
            // And then create the information from this object
            console.time('test')
            const callEvents = getAllCallEvents(skypeConversation)
            let callInformationArray = []
            callEvents.forEach(call => {
                let callObject = createCallInformationObject(call, callInfo)
                if (callObject) {
                    // /console.log(callObject)
                    callInformationArray.push(callObject)
                }
            })
            console.log(callInformationArray)
            console.timeEnd('test')
        }
        reader.readAsText(e.target.files[0]);
    })
})

function addToArray(array, object) {
    array.push(object)
    console.log(array)
    return array
}

/**
 * Gets all the calls from every conversation
 * @param {Array} conversations
 */
function getAllCallEvents(conversations) {
    let callEvents = []
    conversations.forEach(conversation => {
        conversation.MessageList.forEach(message => {
            if (message.messagetype === 'Event/Call') {
                callEvents.push(message)
            }
        })
    })

    return callEvents
}

/**
 * Creates the call information object from the Skype Import data
 * @param {Object} call
 * @param {Object} CallInformationObject
 * @returns CallInformationObject with filled data
 */
function createCallInformationObject(call, CallInformationObject) {
    let parser = new DOMParser(),
        callInformation = parser.parseFromString(call.content, 'text/xml'),
        callParticipents = callInformation.getElementsByTagName('name'),
        callIdentifier = callInformation.getElementsByTagName('partlist')[0],
        callType = callIdentifier.attributes['type'],
        callDate = new Date(call.originalarrivaltime),
        callEventId = callIdentifier.attributes['callId'],
        callDurationArray = callInformation.getElementsByTagName('duration'),
        callDuration = null

    if (!callType) {
        return
    }
    if (!callEventId) {
        return
    }
    if (callDurationArray.length !== 0) {
        callDuration = callDurationArray[0].innerHTML
    }

    CallInformationObject.callType = callType.value
    CallInformationObject.callId = callEventId.value
    CallInformationObject.whoStartedCall = call.displayName
    CallInformationObject.callDate = callDate
    CallInformationObject.callType = callType.value
    CallInformationObject.duration = callDuration

    callParticipents = getCallParticipents(callParticipents)
    CallInformationObject.participentOne = callParticipents[0]
    CallInformationObject.participentTwo = callParticipents[1]

    if (!CallInformationObject.whoStartedCall) {
        CallInformationObject.whoStartedCall = CallInformationObject.participentOne
    }

    return CallInformationObject
}

function getCallParticipents(callGuests) {
    let callParticipents = [
        callGuests[0].innerHTML,
        callGuests[1].innerHTML,
    ]

    return callParticipents
}

EDIT: This is the format of the object being created

 { whoStartedCall: "Samuel Durrant-Walker", participentOne: "Samuel Durrant-Walker", participentTwo: "Yiannis Papadopoulos", duration: null, timeStarted: false, timeEnded: false, callId: "a15882cb-3a28-4d6d-a301-f8e8acb014a3", callDate: Date Wed Apr 22 2020 13:16:54 GMT+0100 (British Summer Time), callType: "started" }
SamWalker
  • 25
  • 1
  • 8
  • Only one object is created. `callInfo` and `callObject` are the same object reference. The same object is mutated over and over again, and pushed repeatedly unto an array. – trincot Nov 13 '21 at 21:31
  • Don’t “create” the same object. `return CallInformationObject` (and the code before it) is wrong — it mutates and then returns the same object *originally given* as an argument. The method name makes this very misleading. – user2864740 Nov 13 '21 at 21:31
  • So, i should remove one of the objects, and simply use just the one and just modify that single object, or not quite got the idea if i go down that route? or, as the second comment suggests, don't pass in the object, create it in the method and return just the object? – SamWalker Nov 13 '21 at 21:33
  • After `let callObject = createCallInformationObject(call, callInfo)` — `callObject` is either null or it is *the same object* as the `callInfo` given to the function. – user2864740 Nov 13 '21 at 21:36
  • Consider “javascript clone object” or “javascript copy object” or actually create the callInfo inside `createCallInformationObject` (so it will be new and not shared); in this case it might not be required as an argument. – user2864740 Nov 13 '21 at 21:37
  • i did move it into the callinfo into the function, and that does seem to have fixed it, not hugely used to the way JS works fully, im doing this to kind of build up my skills – SamWalker Nov 13 '21 at 21:41

0 Answers0