1

Working through an Angular2 tutorial. The challenge was to create a 'tweet' component that used a 'tweet' service to retrieve its posts.

The service is to return an array of hard-coded tweets. This is just for the sake of exercise; obviously not efficiency. However, the service can only return an array of strings so I am not sure how to return an array of HTML that can then be rendered as HTML rather than text in the view. I've read up and seen that there are of course better ways of accomplishing this than through a service, perhaps through a directive. However this is what the challenge is.

This is what I've come up with so far. The view renders the array of tweets from the service as text. Everything else works fine as I tested it with the service returning an array of strings which rendered as planned.

app.component.ts:

import {Component} from 'angular2/core';

import {TweetComponent} from './tweet.component'

@Component({
    selector: 'my-app',
    template: `
        <tweet></tweet>
    `,
    directives: [TweetComponent]
})
export class AppComponent { 

}

tweet.component.ts:

import {Component} from 'angular2/core'
import {TweetService} from './tweet.service'
@Component ({
    selector: 'tweet',
    template: `
    <li *ngFor="#tweet of tweets">
        {{tweet}}
    </li>

    `,

    providers: [TweetService]
})

export class TweetComponent {
    tweets;
    constructor(tweetService: TweetService){
    this.tweets = tweetService.getTweets();
} 
}

tweet.service.ts:

export class TweetService {
    getTweets() {
        return [`
        <div class="media">
         <div class="media-left">
        <a href="#">
          <img class="media-object" src="http://lorempixel.com/100/100/people/?1" alt="...">

        </a>
        </div>
      <div class="media-body">
        <h4 class="media-heading">Tweet 1<br>Media Title 1?<br><like></like></h4>
      </div>
    </div>
       `,
        `
        <div class="media">
         <div class="media-left">
        <a href="#">
          <img class="media-object" src="http://lorempixel.com/100/100/people/?2" alt="...">

        </a>
        </div>
      <div class="media-body">
        <h4 class="media-heading">Tweet 2<br>Media Title 2<br><like></like></h4>
      </div>
    </div>`
        ];
    }
    }
Alfonso Giron
  • 279
  • 4
  • 11
  • Hey, possible duplicate: http://stackoverflow.com/questions/31548311/angular-2-html-binding – Harry Ninh Jun 15 '16 at 02:16
  • Just use `innerHTML` or `outerHTML` property – yurzui Jun 15 '16 at 02:16
  • Services do not normally return HTML. I suggest you put the HTML into your TweetComponent's template -- inside the ngFor loop. Return an array of objects from your service. Each object should contain the data you need to fill out the ngFor template. – Mark Rajcok Jun 15 '16 at 02:19
  • Got you. I actually don't exactly know how to use objects in this case. I took your suggestion and put the html in the component. I tried returning an array of tweets as strings like so ["tweet1","tweet2"]. I then interpolated {{tweet}} into where I want the tweet, which worked. However I don't quite grasp how to do this for multiple properties using objects. And I'm guessing the interpolation would be something like {{tweet.property}}? – Alfonso Giron Jun 15 '16 at 02:44
  • @AlfonsoGiron service only concern with data not view part because service need to inject any other component and can you show me full code of `tweet.service` – uzaif Jun 15 '16 at 02:55
  • Check this out if you're still around. For example I have this code in my template : `

    {{tweet}}
    {{title}}

    ` .... then what would I return in my service to fill out the {{tweet}} and {{title}} interpolations `export class TweetService { getTweets() { return []; }` }
    – Alfonso Giron Jun 15 '16 at 03:53

1 Answers1

3

In tweet.component.ts use innerHTML:

import {Component} from 'angular2/core'
import {TweetService} from './tweet.service'
@Component ({
    selector: 'tweet',
    template: `
    <li *ngFor="#tweet of tweets">
        <span [innerHTML]="tweet"></span>
    </li>

    `,
    providers: [TweetService]
})

by the way, if you are using more recent angular2 version you should change

<li *ngFor="#tweet of tweets">

to

<li *ngFor="let tweet of tweets">
Tomer Almog
  • 3,604
  • 3
  • 30
  • 36
  • Works well thank you. Do you know how I could return an array of objects that I could then use interpolations for. For example, {{title}} for the title of the pose, then {{tweet}} for the actual tweet, then maybe even {[src}} to plug in an image. So titles could be "title1", "title2", etc. Same for tweets and src. How would that return array look? So I guess the interpolation would be something like {{tweet.property}} or so. – Alfonso Giron Jun 15 '16 at 03:59
  • in tweet.service.ts return an array of objects like return [{title: 'title1', html: '
    ...
    },{title: 'title1', html: '
    ...
    }]; then in your template you can use tweet.html or tweet.title etc.
    – Tomer Almog Jun 15 '16 at 16:39