Agrega la funcionalidad para hacer Like a un artista

Clase 24 de 36Curso de React Native 2016

Resumen

Ya tenemos todo listo para agregar los likes en nuestro componente de ArtistBox.
Vamos a wrappear (envolver) nuestro ícono de corazón con un componente que ya hemos utilizado: TouchableOpacity con un callback para el método onPress:

<TouchableOpacity onPress={this.handlePress}>
...
TouchableOpacity>

Y algo que nos permite hacer React es guardar los componentes en variables (o constantes) dependiendo de valores, así podemos mostrar un corazón rojo relleno o uno gris vacío de acuerdo a la variable liked en el estado del componente:

const likeIcon = this.state.liked ?
      "ios-heart" size={30} color="#e74c3c" /> :
      "ios-heart-outline" size={30} color="gray" />

Y utilizarlo dentro del TouchableOpacity así:


    {likeIcon}

Ahora para guardar el like en Firebase debemos importar nuestro firebaseDatabase y además usar la referencia con el id del artista, algo que nos venía en los datos de la API de last.fm.

Primero en el api-client.js debemos mapear el id del artista en el método getArtists():

function getArtists() {
  return fetch(URL)
    .then(response => response.json())
    .then(data => data.topartists.artist)
    .then(artists => artists.map(artist => ({
      id: artist.mbid,
      name: artist.name,
      image: artist.image[3]['#text'],
      likes: 200,
      comments: 140
    })))
}

Y en el handlePress llamamos al método de toggleLike que debemos crear también:

this.toggleLike()

Creamos el método toggleLike de la siguiente manera usando el código que nos provee Firebase pero adaptándolo un poco a nuestras necesidades:

toggleLike = (liked) => {
    const { uid } = firebaseAuth.currentUser
    this.getArtistRef().transaction(function (artist) {
      if (artist) {
        if (artist.likes && artist.likes[uid]){
          artist.likeCount--;
          artist.likes[uid] = null;
        } else {
          artist.likeCount++;
          if (!artist.likes) {
            artist.likes = {};
          }
          artist.likes[uid] = true;
        }
      }
      return artist || {
        likeCount: 1,
        likes: {
          [uid]: true
        }
      }
    })
  }

Ahora nos falta agregar un listener en el método componentWillMount para que estemos escuchando los cambios que suceden en el objeto guardado en Firebase, para poder actualizar la cantidad de likes:

componentWillMount() {
    const { uid } = firebaseAuth.currentUser

    this.getArtistRef().on('value', snapshot => {
      const artist = snapshot.val()
      this.setState({
        likeCount: artist.likeCount,
        liked: artist.likes[uid]
      })
    })
  }

Y también debemos actualizar nuestro método handlePress para que tome sólo los datos que vienen desde Firebase y no haga nada con el estado del componente:

handlePress = () => {
    this.toggleLike()
  }

Por último el método render debe tomar la cantidad de likes del estado del componente y no de los likes que traía el artista que eran siempre 200 (debemos borrar esa línea en api-client.js también):

render() {
    const { image, name, comments } = this.props.artist
    const likeIcon = this.state.liked ?
      "ios-heart" size={30} color="#e74c3c" /> :
      "ios-heart-outline" size={30} color="gray" />

    const { likeCount } = this.state

    return (
      
        
        
          {name}
          
            
              this.handlePress}>
                {likeIcon}
              
              {likeCount}
            
            
              "ios-chatboxes-outline" size={30} color="gray" />
              {comments}
            
          
        
      
    );
  }

Ahora sí, ya tenemos una aplicación donde nos podemos loguear con Facebook y podemos ver en tiempo real las interacciones de otros usuarios. Sólo resta agregar la funcionalidad para que los usuarios puedan realizar comentarios de cada artista.

      Agrega la funcionalidad para hacer Like a un artista