Обновить поля во вложенных объектах в Typescript / Javascript - PullRequest
0 голосов
/ 06 сентября 2018

В Firestore вы можете обновить поля во вложенных объектах точечной нотацией (https://firebase.google.com/docs/firestore/manage-data/add-data?authuser=0#update_fields_in_nested_objects).. Интересно, как заставить это работать в Typescript / Javascript.

Например, следующий объект:

const user = {
    id: 1
    details: {
        name: 'Max',
        street: 'Examplestreet 38',
        email: {
            address: 'max@example.com',
            verified: true
        }
    },
    token: {
        custom: 'safghhattgaggsa',
        public: 'fsavvsadgga'
    }
}

Как я могу обновить этот объект со следующими изменениями:

details.email.verified = false;
token.custom = 'kka';

Я уже обнаружил, что Lodash имеет функцию набора:

_.set(user, 'details.email.verified', false);

Недостаток: Мне нужносделать это для каждого изменения. Является ли это уже метод для обновления объекта с помощью объекта (как сделал Firestore)?

const newUser = ANYFUNCTION(user, {
    'details.email.verified': false,
    'token.custom' = 'kka'
});

// OUTPUT for newUser would be
{
        id: 1
        details: {
            name: 'Max',
            street: 'Examplestreet 38',
            email: {
                address: 'max@example.com',
                verified: false
            }
        },
        token: {
            custom: 'kka',
            public: 'fsavvsadgga'
        }
    }

Кто-нибудь знает хорошее решение для этого? Я уже нашел больше решений, если я толькохотите изменить одно поле ( Динамически установить свойство вложенного объекта ), но нет решения для более чем одного поля с одним методом

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

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

function set(obj, path, value) {
    let parts = path.split(".");
    let last = parts.pop();
    let lastObj = parts.reduce((acc, cur) => acc[cur], obj);
    lastObj[last] = value;
}

set(user, 'details.email.verified', false);

если вы хотите объединить 2 объекта, то это немного сложнее:

function forEach(target, fn) {
    const keys = Object.keys(target);
    let i = -1;
    while (++i < keys.length) {
        fn(target[keys[i]], keys[i]);
    }
}

function setValues(obj, src) {
    forEach(src, (value, key) => {
        if (value !== null && typeof (value) === "object") {
            setValues(obj[key], value);
        } else {
            obj[key] = value;
        }
    });
}

let obj1 = {foo: {bar: 1, boo: {zot: null}}};
let obj2 = {foo: {baz: 3, boo: {zot: 5}}};

setValues(obj1, obj2);

console.log(JSON.stringify(obj1));
0 голосов
/ 06 сентября 2018

Одно решение в сочетании с методом lodash _.set может быть:

function setObject(obj, paths) {
        for (const p of Object.keys(paths)) {
            obj = _.set(obj, p, paths[p]);
        }
        return obj;
}
...