0

So, im a little bit lost here and i need some help. I have a json that come from the server with data that i dont know.

Based on that i found a solution to display the data on html here on SO: https://stackoverflow.com/a/50352965/9721446

But the problem is that each "item" is an entry from array, so if i ngfor array, it outputs each line as an item, and i want the item to be all entries of each result.

heres the html:

<ng-container *ngFor="let item of singleArray | paginate: { itemsPerPage:411, currentPage: p} ">
         <!-- All the entries -->
         <div class="w3-container">

          <!-- Table view-->
          <table class="center">
             <tr *ngIf="!item.tag.includes('URL') && !item.tag.includes('linkChal')">
              <td><div class="col-xs-auto thick">{{item.tag.toLowerCase() | translate}}</div></td>
               <td class="tab">{{item.value}}</td>
               </tr>
               <tr *ngIf="item.tag.includes('URL')">
                        <td>Link da entrada: </td>
                        <td> <a href="{{item.value}}">- Ver mais -</a></td>
                </tr>
                <tr *ngIf="item.tag.includes('linkChal')">
                         <td>Link do Challenge: </td>
                         <td> <a href="{{item.value}}">- Challenge -</a></td>
                </tr>
           </table>

           <div style="background-color: #ff7d2a">
               <ul *ngIf=" item.tag.includes('---------')"><p>New Entry</p></ul>
               </div>
            </div>
 </ng-container>

Ts:

for(let i in res)
        {

            //array with entities from json
            this.entity.push(i);

            for(let j in res[i])
            {
                let val = Number(j)+1;
                this.cont.push(i +"  - nº: " + val );
                this.singleArray.push({
                    tag: i,
                    value: val
                });

                for(let t in res[i][j])
                {
                    this.test.push(t);
                    this.cont.push(t +" - "+ this.responseList[i][j][t]) ;

                    if(t.split(".",2)[1] === "CompositeId")
                    {
                        this.test.push("URL:");
                        //Get the id
                        this.cont.push(this.moduleName + "/" + t.split(".",2)[0] + "/" + this.responseList[i][j][t].match(/=(.*)_/)[1]);
                        //debugger;
                        this.singleArray.push({
                            tag: "URL:",
                            value: this.moduleName + "/" + t.split(".",2)[0] + "/" + this.responseList[i][j][t].match(/=(.*)_/)[1]
                        });
                    }
                    else if(t.split(".",2)[1] === "Challenge")
                    {
                        this.singleArray.push({
                            tag: "linkChal",
                            value: this.moduleName + "/" +t.split(".",2)[1] + "/" + this.responseList[i][j][t].match(/=(.*)_/)[1]
                        });
                    }
                    else {
                        this.singleArray.push({
                            tag: t,
                            value: this.responseList[i][j][t]
                        });
                    }

                }
                this.test.push("\n");
                this.cont.push("\n");
                this.singleArray.push({
                    tag: "---------\n",
                    value: "--------\n"
                });

                 //it ends an item here 
            }
        }

Heres the output i have with that:

results

Each one line is an entry from the array, the big question is, how to transform all lines/entries until "New Entry" and made an single item to ngfor and display data into a card that i already have..)

I've tried to create an array and push the singleArray into it (hoping each entry of that new array was an item that i want), at the end of for(let j in res[i]) on .ts but it just repeated all the entries creating a bunch of entries.. here, at the end of that for, i've tried to push an array with something, then ngfor it (it gives me the number items that i want, but then i dont have the results to access them..)

Has anyone had this problem before? thanks in advance

Edit: here's what singleArray looks like:

enter image description here

Bruno
  • 404
  • 4
  • 16

2 Answers2

0

Your best bet here is to follow the single responsibility principal and separate the concerns of each class.

Stop trying to do this all in the view and separate out the responsibility of formatting the data and the problem will seem much simpler.

  • Make a new class to define the model you want your view to use
  • Have your view implement this new ideal model that you control
    • Generate some test data to make get this looking like what you want
  • Create a new class who's entire responsibility is to turn the external model from the api response into this new internal model
    • json2ts may help generate a better external model from the response, but it may not be of much use in this case

Once you have done the above, based on your sample output, it should be fairly simple to convert from the external model into the internal model. It's hard to convey this, but assuming the hyphens are the item separator you could simply do something like the following:

    const externalItems = // data from api
    const internalItems = [];
    let currentInternalItem = {};

    externalItems.forEach(item => {
     if (item.tag.startsWith('---------')) {
         internalItems.push(currentInternalItem);
         currentInternalItem = {};
     } else {
        currentInternalItem[item.tag] = item.value;
     }
    });

This would group the array back into an object that you can use in your view.

Paul Coghill
  • 667
  • 6
  • 27
  • I assume that i am using Single responsibility principal, because each module as it's own objectve: - I got the service that retrieves the server JSON, which i never know whats in it. - i got the .ts that reads the json and creates an array key - value to push every item that comes. - then i use html to display it the best way i can. I can't generate an interface based on json because i never know whats inside... Im trying to make the question clear.. because the "------" and etc is added by me on .ts side, to separate each result.. – Bruno Jun 01 '18 at 09:43
  • Ok, that makes it a bit clearer. The sample code I've given will change but the principal will stay the same. In the sample code I've given I iterate through a list of objects and generate a new object from each result. Instead of pushing everything to a flat array of { tag, value } - you can generate an array of "Card" objects, with all the tag/value pairs for each card. Then in your view you can generate a Card view for each Card object. – Paul Coghill Jun 01 '18 at 11:00
0

I think I'm complicating too much.. The objective here is to display what comes from JSON into specific locations, like a card, with header and content, to better display the results.

I have a service that gives me a JSON, that i never knows what inside, that depends on the search term and can bring much information. For example:

If the term is "Idea": enter image description here

If the term is Challenge:
enter image description here

My .ts file is only console.log what comes from the api.

 ngOnInit() {
    var setting = {setting to connect the server..}
    enter code here
    $.ajax(settings).done((rest) => this.response(rest));
    }

response(res){

        console.log(res);
}

How can i display that data the way i want? Sorry for the long post, and for not beeing objective on the main question.

Bruno
  • 404
  • 4
  • 16