IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

TypeScript Discussion :

Convertion de JSon en object TypeScript Angular


Sujet :

TypeScript

  1. #1
    Membre habitué Avatar de Badshade23
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2014
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2014
    Messages : 203
    Points : 133
    Points
    133
    Par défaut Convertion de JSon en object TypeScript Angular
    Bonjour,

    J'apprends en autodidacte le merveilleux monde d'Angular, mais je rencontre actuellement un problème :

    Je désire réaliser un site web et pour ce faire j'utilise en back Spring et en front Angular 7.

    Et la, j'ai un souci.

    J'ai actuellement 3 entités : le constructeur, la catégorie et le vaisseau.

    Et mon vaisseau a bien entendu un attribut constructeur (le constructeur du vaisseau) et une catégorie (chasseur ...).

    Après demande à mon service. (vaisseau.service.ts)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public host = 'http://localhost:8080';
     
      constructor(private httpClient: HttpClient) {
      }
     
      public getVaisseaux(page: number, size: number) {
        return this.httpClient.get(this.host + '/vaisseaus?page=' + page + '&size=' + size);
      }
    il me retourne le JSon suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    {
      "_embedded" : {
        "vaisseaus" : [ {
          "nom" : "nomVaisseau",
          "description" : "Description du vaisseau",
          "image" : "http://127.0.0.1/img/Vaisseaux/2.jpg",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/vaisseaus/2"
            },
            "vaisseau" : {
              "href" : "http://localhost:8080/vaisseaus/2"
            },
            "constructeur" : {
              "href" : "http://localhost:8080/vaisseaus/2/constructeur"
            },
            "categorie" : {
              "href" : "http://localhost:8080/vaisseaus/2/categorie"
            },
            "utilisateurs" : {
              "href" : "http://localhost:8080/vaisseaus/2/utilisateurs"
            }
          }
        } ]
      },
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/vaisseaus{&sort}",
          "templated" : true
        },
        "profile" : {
          "href" : "http://localhost:8080/profile/vaisseaus"
        },
        "search" : {
          "href" : "http://localhost:8080/vaisseaus/search"
        }
      },
      "page" : {
        "size" : 5,
        "totalElements" : 1,
        "totalPages" : 1,
        "number" : 0
      }
    }
    que j'appelle ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    public constructeurs: any;
      public pages: Array<number>;
      private currentPage = 0;
      private size = 2;
      private totalPages: number;
      private currentKeyword = '';
     
      constructor(private constService: ConstructeurService, private router: Router) {
      }
     
      ngOnInit() {
        this.onGetConstructeurs();
      }
     
      /**
       * Méthode qui permet de récupérer la liste des constructeurs
       * selon la page et le nombre de constructeur qu'elle peut contenir
       */
      onGetConstructeurs() {
        this.constService.getConstructeurs(this.currentPage, this.size)
          .subscribe(data => {
            this.constructeurs = data;
            this.totalPages = data['page'].totalPages;
            this.pages = new Array<number>(this.totalPages);
          }, err => {
            console.log(err);
          });
      }
    et dans mon template :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    <table *ngIf="vaisseaux" class="table">
            <!-- Si il n'y a pas de vaisseaux en BDD n'affiche pas le tableau-->
            <thead class="thead-dark">
            <tr>
              <th scope="col">Vaisseau</th>
              <th scope="col">Nom</th>
              <th scope="col">Constructeur</th>
              <th scope="col">Catégorie</th>
              <th scope="col">Action</th>
            </tr>
            </thead>
            <tbody>
            <tr *ngFor="let p of vaisseaux._embedded.vaisseaus">
              <td class="col-md-2 align-middle"><img src="{{p.image}}"></td><!-- {{p.image}} -->
              <td class="col-md-2 align-middle text-center">{{p.nom}}</td>
              <td class="col-md-2">{{p.constructeur.nom}}</td>
              <td class="col-md-2">{{p.categorie.nom}}</td>
              <td class="col-md-2 align-middle  text-center">
                <a (click)="voirVaisseau(p)" class="btn btn-primary"><i aria-hidden="true"
                                                                        class="fa fa-plus-circle"></i></a>
                <a (click)="onEditVaisseau(p)" class="btn btn-warning m-2">Modifier</a>
                <a (click)="onDeleteVaisseau(p)" class="btn btn-danger">Supprimer</a></td>
            </tr>
            </tbody>
          </table>
    et l'erreur suivante apparaît :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ERROR TypeError: "_v.context.$implicit.constructeur is undefined"
        View_LstVaisseauComponent_3 LstVaisseauComponent.html:35
        Angular 29
        RxJS 5
        Angular 9
    LstVaisseauComponent.html:34:56
        View_LstVaisseauComponent_3 LstVaisseauComponent.html:34
        Angular 15
        RxJS 5
        Angular 9
    Je n'arrive donc pas à avoir le constructeur du vaisseau comme sa catégorie ....

    J'ai regardé sur Google et autre les différentes façons de charger le JSon (via des interfaces dans Angular, ou des constructeurs qui prennent en paramètre le Json qui est parcouru comme un tableau ...)

    Mais rien avec des

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    "vaisseau" : {
              "href" : "http://localhost:8080/vaisseaus/2"
            },
    Comme si c’était charger en lazy ...
    Je ne comprends pas d'où vient mon problème ... Du coté du Back où il faut que je donne des paramètres à mon REST pour qu'il envoie à chaque fois toutes les informations et non des liens qui pointent vers ou c'est à Angular de charger les différents object en chargent à partir des liens ?


    Merci d'avance pour toute aides ^^.

  2. #2
    Membre extrêmement actif
    Avatar de Sodium
    Femme Profil pro
    Développeuse web
    Inscrit en
    Avril 2014
    Messages
    2 324
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeuse web

    Informations forums :
    Inscription : Avril 2014
    Messages : 2 324
    Points : 2 006
    Points
    2 006
    Billets dans le blog
    1
    Par défaut
    Houlala j'ai buggé un bon moment, ne comprenant pas que tu parlais de "constructeur" comme fabricant et pas comme méthode constructeur d'une classe.
    Il faut que tu utilises JSON.parse pour transformer le JSON renvoyé en objet JavaScript exploitable.

  3. #3
    Membre habitué Avatar de Badshade23
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2014
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2014
    Messages : 203
    Points : 133
    Points
    133
    Par défaut
    Désoler pour le terme de "constructeur" ^^.

    Et il faut que j'uitilise "JSON.parse" même avec HttpClient ?

    J'ai trouvé ce site aussi : https://davidpine.net/blog/angular-http-gotchas/ qui dit que (traduit à la peut pres ^^ ) : Le problème spécifique est que l'implémentation sous-jacente de Angular n'instancie pas votre objet. Au lieu de cela, il le convertit simplement en tant que type donné. En fin de compte, Angular effectue une JSON.parseréponse sur le corps de la réponse.

    Et il part sur quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public getDetails(): Promise<Details[]> {
        return this.http
                   .get<Details>(`${this.baseUrl}/api/details`)
                   .map(response => {
                       const array = JSON.parse(response.json()) as any[];
                       const details = array.map(data => new Details(data));
                       return details;
                   })
                   .toPromise();
    }
    On dirait qu'il existe trente mille façons de faire, je me perds un peut dans tout ça ^^.
    Laquelle est la plus propre ? La plus stable ?

  4. #4
    Membre extrêmement actif
    Avatar de Sodium
    Femme Profil pro
    Développeuse web
    Inscrit en
    Avril 2014
    Messages
    2 324
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeuse web

    Informations forums :
    Inscription : Avril 2014
    Messages : 2 324
    Points : 2 006
    Points
    2 006
    Billets dans le blog
    1
    Par défaut
    Dans son exemple, il passe une interface Details à sa requête get, ce qu'à vrai dire je ne connaissais même pas. Dans ton cas tu fais un simple get, donc ça te retourne la réponse brute de ce que tu as demandé, qu'il faut parser.

  5. #5
    Membre habitué Avatar de Badshade23
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2014
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2014
    Messages : 203
    Points : 133
    Points
    133
    Par défaut
    D'accord et justement depuis mes recherches, je vois énormément de personnes / tutos qui utilise les interfaces au lieu de class.
    Il y a t'il une préférence ? La meilleure solution selon vous ?

  6. #6
    Membre habitué Avatar de Badshade23
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2014
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2014
    Messages : 203
    Points : 133
    Points
    133
    Par défaut
    Ou encore des mappers comme celui-ci : https://www.npmjs.com/package/json2typescript

  7. #7
    Membre habitué Avatar de Badshade23
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2014
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Décembre 2014
    Messages : 203
    Points : 133
    Points
    133
    Par défaut
    Au final, j'ai utilisé les projections qui me permette de récupérer ce que je désire.
    Ce format de JSON est dû à Spring HATEOAS qui au lieu de fournir les sous entités envoie tout simplement un lien qui pointe vers elle.
    De nombreuses solutions sont disponibles sur Internet pour contourner ce "problème" personnellement j'ai opté pour les projections.
    Voici un petit exemple pour ceux que ça intéresses:
    Coter Back :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    /**
     * Notez que notre projection est définie comme une interface avec une
     * annotation @Projection . Nous pouvons utiliser l' attribut name pour
     * personnaliser le nom de la projection, ainsi que les attributs types pour
     * définir les objets auxquels elle s'applique.
     *
     * @author BadShade
     *
     */
    @Projection(name = "vaisseauProjection", types = Vaisseau.class)
    public interface VaisseauProjection {
     
    	public long getId();
    	public String getNom();
    	public String getDescription();
    	public String getImage();
    	public Constructeur getConstructeur();
    	public Categorie getCategorie();
     
    }
    Côter Front :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      public getVaisseauxByKeyword(mc: string, sort: string, order: string, page: number, size: number): Observable<PageableVaisseaux> {
        return this.httpClient.get<PageableVaisseaux>(this.host + '/vaisseaus/search/byNomPage?mc=' + mc + '&sort=' + sort + ','
          + order + '&page=' + page + '&size=' + size + '&projection=vaisseauProjection');
      }
    Voilà merci encore pour l'aide et l'intérêt donnée à mon problème.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] Deserialisation Json vers object
    Par Armakorhall dans le forum C#
    Réponses: 3
    Dernier message: 27/09/2012, 08h42
  2. Convertion en JSON problème
    Par Quantactique dans le forum Langage
    Réponses: 4
    Dernier message: 16/05/2012, 13h22
  3. Convertion d'un tableau Object en tableau d'une classe spécifique
    Par 0redd dans le forum Collection et Stream
    Réponses: 8
    Dernier message: 22/07/2010, 01h20
  4. [XSLT] Convertion XML/JSON
    Par leTiDevDu54 dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 08/06/2010, 16h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo