1
votes

Fusion de certaines valeurs dans un objet Javascript

Je me demande s'il est possible de fusionner certaines valeurs d'un objet avec un tableau / objet. Je développe actuellement un module pour créer un devis et à chaque fois qu'une valeur est modifiée sous la forme, je veux envoyer les données du formulaire au serveur (appel async ajax) pour enregistrer automatiquement le devis. J'obtiens les données du formulaire (par la fonction getValues ​​() de react hook form ) comme indiqué sur la capture d'écran ci-dessous:

 Données de formulaire renvoyées par < code> getValues ​​() </code>

Comme le montre la capture d'écran, il y a plusieurs lignes [0] et lignes [1] entrées qui sont toutes des entrées séparées. Pour l'envoyer au serveur, j'ai besoin des données suivantes:

client_id: "686",
condition: "7",
...
lines: {
    0: {
        amount: 1,
        description: 'Test line 1',
        price: 100,
    },
    1: {
        amount: 1,
        description: 'Test line 2',
        price: 200,
    }
},
...

Quelqu'un ici sait comment je peux faire pour convertir mes données en quelque chose comme l'exemple ci-dessus? Merci d'avance!


0 commentaires

3 Réponses :


0
votes

En général, pour fusionner des valeurs, les gens devraient vérifier Object.assign () .

Dans ce cas particulier, pour passer de la deuxième capture d'écran à la première, vous avez peut-être utilisé une boucle, quelque chose comme:

let newObject = {};
for (let lineIndex=0; lineIndex<lines.length; lineIndex++) {
    for (let fieldIndex=0; fieldIndex<Object.keys(lines[lineIndex]).length; fieldIndex++) {
        let newKey = "lines["+lineIndex+"]."+fieldIndex<Object.keys(lines[lineIndex])[fieldIndex];
        newObject[newKey] = lines[lineIndex][Object.keys(lines[lineIndex])[fieldIndex]]
    }
}

Pour aller dans l'autre sens, vous ferait essentiellement l'inverse. Les détails de la meilleure façon de procéder dépendent de la prévisibilité de votre ensemble de champs et de la connaissance de la longueur. Sinon, vous pourriez faire des suppositions en itérant sur les clés de l'objet plus plat et en faisant des tests comme if (Object.keys (flatterObject) [index] .startsWith ("lines [")) .


1 commentaires

Salut @WBT, merci pour la réponse. C'est l'inverse en fait, l'image est ce que j'obtiens et le code "exemple" est ce que je veux qu'il soit. J'espérais qu'il y aurait une fonction js «par défaut» pour cela, mais apparemment pas. Je vérifierai certainement la façon dont vous suggérez. L'ensemble de données pour un champ est toujours le même, donc je l'ai déjà obtenu pour moi, ce qui est bien;)



0
votes

Oui, il existe un moyen de faire ce que vous voulez, mais avant tout cela, je vous suggère de plonger plus en profondeur sur la bibliothèque que vous utilisez. Voici comment gérer les tableaux dans React Hook Form: https: // react-hook-form. com / advanced-usage # FieldArrays

Après avoir "corrigé" cela, si vous voulez toujours que lines: {} soit un objet, pas un tableau, alors un simple tableau reduction peut le construire pour vous.


1 commentaires

Salut, merci pour la réponse. J'utilise déjà FieldArrays de React Hook Form. C'est ainsi que getValues ​​() renvoie tout pour moi.



1
votes

Voici une solution pour toute clé avec des points. Élargissement de la solution pour les crochets:

var source = {
    id:12,
    cond:"true",
    'lines[0].amount':"1",
    'lines[0].description':"a1",
    'lines[1].amount':"1",
    'lines[1].description':"a1",
};

var target = {};
for (var key in source) {
    if (source.hasOwnProperty(key)) {
        set(target, key, source[key])
    }
}

function set(obj, path, value) {

    obj = typeof obj === 'object' ? obj : {};    
    path = path.replace("[",".").replace("]","")
    var keys = Array.isArray(path) ? path : path.split('.');   
    var curStep = obj;

    for (var i = 0; i < keys.length - 1; i++) {

        var key = keys[i];        
        if (!curStep[key] && !Object.prototype.hasOwnProperty.call(curStep, key)){            
            var nextKey = keys[i+1];
            var useArray = /^\+?(0|[1-9]\d*)$/.test(nextKey);
            curStep[key] = useArray ? [] : {};
        }        
        curStep = curStep[key];
    }
    var finalStep = keys[keys.length - 1];
    curStep[finalStep] = value;
};


1 commentaires

Hey @MichaelGoldenberg, a essayé votre solution (ne l'a réécrit que dans ES6) et a fait exactement ce que j'espérais. Marquera ceci comme la bonne réponse. Merci!