Я получаю тот же объект внутри для l oop для модификации в angular - PullRequest
0 голосов
/ 15 апреля 2020

Итак, я хочу выполнить al oop, который существенно изменяет структуру элемента в итерации. Но для модификации у меня есть предопределенный объект структуры, который я установил как объект по умолчанию. Теперь, пока я зацикливаюсь на каждом элементе массива объектов (массив, который нужно изменить), я отправляю объект по умолчанию вместе с текущим элементом какой-то другой функции, которая по существу возвращает измененный объект. Но происходит то, что объект по умолчанию, который я передаю, изменяется после каждой итерации. Как мне остановить изменение объекта по умолчанию?

Например, у меня есть эти данные, которые я хочу изменить

[{
    "name": "Sample 1",
    "session_id": "sample_id_1",
    "created": "2020-04-14T06:45:05.494Z",
    "isUploaded": false,
    "username": "username1",
    "topics": [
        {
            "name": "2",
            "isUploaded": true,
            "topic_id": "2"
        },
        {
            "name": "3",
            "isUploaded": true,
            "topic_id": "3"
        }
    ]
},
{
    "name": "Sample_2",
    "session_id": "sample_id_2",
    "created": "2020-04-14T05:43:10.643Z",
    "isUploaded": false,
    "username": "username2",
    "topics": [
        {
            "name": "2",
            "isUploaded": true,
            "topic_id": "2"
        },
        {
            "name": "1",
            "isUploaded": true,
            "topic_id": "1"
        },
        {
            "name": "4",
            "isUploaded": true,
            "topic_id": "4"
        }
    ]
}]

И массив объектов по умолчанию, который я хочу использовать:

[
    {
      topic_id: '1',
      topic_status: '-1',
      topic_name:
      {
        en: 'Some english text 1?',
        hi: 'some hindi text 1?'
      },
      isPlayed: false,
      status: false
    }, {
      topic_id: '2',
      topic_status: '-1',
      topic_name: {
        en: 'some english text 2?',
        hi: 'some hindi text 2?'
      },
      isPlayed: false,
      status: false
    },
    {
      topic_id: '3',
      topic_status: '-1',
      topic_name: {
        en: 'some english text 3?',
        hi: 'some hindi text 3?'
      },
      isPlayed: false,
      status: false
    },
    {
      topic_id: '4',
      topic_status: '-1',
      topic_name: {
        en: 'some english text 4?',
        hi: 'some hindi text 4?'
      },
      isPlayed: false,
      status: false
    }
  ]

Теперь я написал это l oop, которое изменит каждый элемент внутри l oop в соответствии с объектом по умолчанию следующим образом:

async getServerSessionsAsLocal(serverSessions) { // serverSessions contains the sample Array of Objects described above
const newArray = [];
const defaultQuestionsForLocal = await this.userService.getUserQuestions(); // this will return the default object Array described above
if (defaultQuestionsForLocal) {
  for (let i = 0 ; i < serverSessions.length; ++i) {
    const generatedSession = this.syncService.generateSession(serverSessions[i], [...defaultQuestionsForLocal]); // this function essentially modifies the serverSession object according to the default object Array
    newArray.push(generatedSession);
  }
}
return [...newArray];

}

Таким образом, функция generateSession работает следующим образом: она ищет ключ тем внутри предоставленного объекта serverSession [i] (зацикливая массив defaultQuestionsForLocal) и сопоставляет его topic_id с topic_id, присутствующим внутри defaultQuestionsForLocal. Если есть совпадение, он обновляет topic_status элемента defaultQuestions до 3, в противном случае он остается без изменений. Теперь, учитывая, что мы модифицируем пример данных с индексом 0 с помощью DefaultArray по умолчанию, результирующий генерируемый сеанс будет выглядеть следующим образом:

{
"name": "Sample 1",
"session_id": "sample_id_1",
"created": "2020-04-14T06:45:05.494Z",
"isUploaded": false,
"username": "username1",
"topics": [
    {
        "name": "1",
        "isUploaded": false,
        "topic_id": "1",
        "topic_status": -1
    },
    {
        "name": "2",
        "isUploaded": true,
        "topic_id": "2",
        "topic_status":3,
    },
    {
        "name": "3",
        "isUploaded": true,
        "topic_id": "3",
        "topic_status": 3,
    },
    {
        "name": "4",
        "isUploaded": false,
        "topic_id": "4",
        "topic_status": -1,
    },
]

}

Теперь возникает проблема, когда я передаю defaultQuestionsArray в функцию generateSession, внутренне он изменяет этот defaultQuestionsArray, присваивает его обратно ключу темы объекта сеанса и возвращает весь объект обратно. Для первой итерации все выглядит нормально, однако для любых последующих итераций массив defaultQuestions модифицируется. Таким образом, после второй итерации ключ topic_status внутри каждого из элементов массива defaultQuestions будет изменен в соответствии с образцом объекта с индексом 2. Так, например, после второй итерации defaultQuestionsArray будет выглядеть следующим образом:

[
{
  topic_id: '1',
  topic_status: '3',
  topic_name:
  {
    en: 'Some english text 1?',
    hi: 'some hindi text 1?'
  },
  isPlayed: false,
  status: false
}, {
  topic_id: '2',
  topic_status: '3',
  topic_name: {
    en: 'some english text 2?',
    hi: 'some hindi text 2?'
  },
  isPlayed: false,
  status: false
},
{
  topic_id: '3',
  topic_status: '3',
  topic_name: {
    en: 'some english text 3?',
    hi: 'some hindi text 3?'
  },
  isPlayed: false,
  status: false
},
{
  topic_id: '4',
  topic_status: '3',
  topic_name: {
    en: 'some english text 4?',
    hi: 'some hindi text 4?'
  },
  isPlayed: false,
  status: false
}

]

Обратите внимание, что третий индексный объект установлен на 3, так как он был изменен в первой итерации, а остальные были изменены в текущей итерации. И поскольку я присваиваю этот результирующий объект ключу тем поставляемого объекта сеанса, ключ тем предыдущего измененного объекта также получает то же значение. Это означает, что после второй итерации newArray будет выглядеть следующим образом:

[{
 "name": "Sample 1",
 "session_id": "sample_id_1",
 "created": "2020-04-14T06:45:05.494Z",
 "isUploaded": false,
 "username": "username1",
 "topics": [
 {
    "name": "1",
    "isUploaded": false,
    "topic_id": "1",
    "topic_status": 3
 },
 {
    "name": "2",
    "isUploaded": true,
    "topic_id": "2",
    "topic_status":3,
 },
 {
    "name": "3",
    "isUploaded": true,
    "topic_id": "3",
    "topic_status": 3,
 },
 {
    "name": "4",
    "isUploaded": false,
    "topic_id": "4",
    "topic_status": 3,
 }
]
}, {
"name": "Sample_2",
"session_id": "sample_id_2",
"created": "2020-04-14T05:43:10.643Z",
"isUploaded": false,
"username": "username2",
"topics": [
    {
        "name": "1",
        "isUploaded": true,
        "topic_id": "1",
        "topic_status": 3
    },
    {
        "name": "2",
        "isUploaded": true,
        "topic_id": "2",
        "topic_status": 3
    },
    {
        "name": "1",
        "isUploaded": true,
        "topic_id": "1",
        "topic_status": 3
    },
    {
        "name": "4",
        "isUploaded": true,
        "topic_id": "4",
        "topic_status": 3
    }
]
}]

Я хочу, чтобы каждый раз, когда я передаю defaultQuestionsArray в функцию генерации сеанса, он всегда должен быть массивом по умолчанию. Есть идеи о том, как это исправить?

1 Ответ

1 голос
/ 15 апреля 2020

Использование:

Object.create(originalTemplateObject);

Если у вас есть проблемы с изменяемым оригиналом, этот метод возвращает копию объекта и его свойств без сохранения ссылок, ref:

Object.create

Затем вы можете изменить копию вместо изменения оригинала, переданного по ссылке.

пример:

, так что ваш шаблон объекта по умолчанию выглядит примерно так это:

{
  topic_id: '1',
  topic_status: '-1',
  topic_name:
  {
    en: 'Some english text 1?',
    hi: 'some hindi text 1?'
  },
  isPlayed: false,
  status: false
}

Вы должны сохранить этот шаблон вне всего вашего кода, потому что должна быть глобальная константа:

const objectTemplate = {
  topic_id: '',
  topic_status: '',
  topic_name:
  {
    en: '',
    hi: ''
  },
  isPlayed: false,
  status: false
}

Здесь у нас есть функция, которая создает объект, а затем возвращает новый объект, используя переданные параметры.

const objectTemplate = {
  topic_id: '',
  topic_status: '',
  topic_name:
  {
    en: '',
    hi: ''
  },
  isPlayed: false,
  status: false
}

const myObjects = [];

function copyObject(...objectValues){

    let i = 0;
    const newObject = Object.create(objectTemplate);
    
    for(let prop in newObject){
       newObject[prop] = objectValues[i];
       i++;
    }

    return newObject;
}

myObjects.push(
  copyObject('1', '-1', {en: 'Some english text 1?',hi: 'some hindi text 1?'}, false, false
));

console.log("array with the object copy: " + "\n");
console.log(myObjects);
console.log("\n" + "original object: " + "\n");
console.log(objectTemplate);

Это пример использования этого метода без модификации исходного объекта.

...