web-dev-qa-db-fra.com

Fonction DocumentReference.set () appelée avec des données non valides. Valeur de champ non prise en charge: un objet Budget personnalisé

Le code ci-dessous fonctionne bien jusqu'à aujourd'hui. Mais je ne sais pas maintenant, cela ne fonctionne pas et donne l'erreur ci-dessous. Pouvez-vous me dire pourquoi?

Erreur: la fonction DocumentReference.set () appelée avec des données non valides. Valeur de champ non prise en charge: un objet Budget personnalisé

 export class Project {
        id: string = null;
        name: string;
        budgetList?: Budget[];
    }

export class Budget {
    id: string;
    amount: number;
    contingency: number = 20;
    budgetGroup: BudgetGroup = new BudgetGroup();
    creationTime: string;
}

code:

  async create(data: DtoProject): Promise<Project> {
    try {
      const projectId: string = this.fireStore.createId();
      const budgets = this.budgetProvider.createBudgets(data.budgetList, projectId);//budgets
      const proj: Project = {
        id: data.id,
        name: data.name,
        budgetList: budgets,//here it has the error
      }
      proj.id = projectId;
      await this.fireStore.doc<Project>(`projects/${projectId}/`).set(proj));//project
      }
 }

  createBudgets(data: Budget[], projectId: string): Budget[] {
    let budgets: Budget[] = [];
    forEach(data, (d) => {
      const budgetId: string = this.fireStore.createId();
      d.id = budgetId;
      budgets.Push(d);
      this.fireStore.doc<Budget>(`projects/${projectId}/budgets/${budgetId}`).set({
        id: budgetId,
        amount: d.amount,
        contingency: d.contingency,
        budgetGroup: d.budgetGroup,
        creationTime: moment().format()
      })
    })
    return budgets;
  }
26
Sampath

Vous devez transformer votre tableau de budgets en un tableau d'objets JavaScript pur .

Premier pas:

const budgets = arrayOfBudget.map((obj)=> {return Object.assign({}, obj)});

Deuxième étape:

const proj: Project = {
      id: data.id,
      name: data.name,
      budgetList: budgets
    }

Alors tu peux y aller.

En passant, lors du développement avec un langage compilant JavaScript, vous ne pouvez pas utiliser d'objets personnalisés. Au lieu de cela, vous devez utiliser des objets JavaScript purs pour enregistrer dans la base de données Firestore.

Par exemple, supposons que vous ayez cette classe ci-dessous:

export class User {
        id: string;
        name: string;
    }

Et vous essayez d'exécuter le code suivant:

 const user = new User();   
 this.db.collection('users').doc().set(user)

Vous obtiendrez une erreur comme:

données invalides. Les données doivent être un objet, mais c'était: un objet utilisateur personnalisé

Maintenant, si vous essayez d'exécuter cette autre ligne de code:

 this.db.collection('users').doc().set(Object.assign({}, user))

Vous verrez que votre objet a été enregistré dans la base de données. Fondamentalement Object.assign fait la même chose que:

this.db.collection('users').doc().set({id: user.id , name: user.name})

Alors, utilisez Object.assign, cela vous fera gagner beaucoup de temps.

[~ # ~] met à jour [~ # ~]

Comme je l'ai souligné dans un commentaire ci-dessous, vous pouvez trouver ce que la documentation dit à propos de Objets personnalisés ici . Comme vous pouvez le constater, un avertissement dit:

// Web utilise des objets JavaScript

Vous trouverez ci-dessous une capture d'écran de ce que dit la documentation.

enter image description here

Vous pouvez stringifier l'objet et analyser à nouveau pour supprimer les noms de classe de l'objet.

const budgets = this.budgetProvider.createBudgets(JSON.parse(JSON.stringify(data.budgetList)), projectId);
9
MalindaK

Vous pouvez également utiliser l'opérateur spread comme:

this.fireStore
  .doc<Project>(`projects/${projectId}/`)
    .set( {...proj} ))

Ça marche pour moi

1
Andres Gardiol

Error indique simplement que les données saisies sont invalides!

J'ai aussi fait face à l'erreur de nulle part, c'est parce que j'ai enlevé le champ de saisie de l'interface qui était censé en obtenir la valeur et le télécharger dans le document d'une collection!

remarque: vérifiez votre code dans le fichier .ts firebase.firestore().collection("some_name").add() / set() si un champ inutile est présent ou non.

0
Vaibhav Dewangan