react-native-render-html Please provide the html or uri prop using api

Created on 11 Jan 2019  路  5Comments  路  Source: meliorence/react-native-render-html

I am facing an issue in rendering html data into my application. I am getting html data from an api and it shows this kind of warning "react-native-render-html Please provide the html or uri prop".
I am able to access the html but the screen comes out to be blank. The html data is not getting rendered.
Find attached my code:
import React, { Component } from 'react';
import {ScrollView, WebView, Animated, Easing, View, Text, StyleSheet, Dimensions, ImageBackground,TouchableOpacity, Button, AsyncStorage} from 'react-native';
import { Constants } from 'expo';
import { Carousel, AnimatedCarouselItem } from 'react-native-sideswipe'; // 0.0.6
import { Card, Badge } from 'react-native-elements'; // 0.18.5
import email from 'react-native-email';
import HTML from 'react-native-render-html';

export default class emailTemplates extends Component {
constructor(props){
super(props);
this.state={
width: Dimensions.get('window'),
content:'',
userId:'',
userToken:'',
htmlContent:''
//emailId:''
};
this.ServerAccess = this.ServerAccess.bind(this);
this.retrieveData = this.retrieveData.bind(this);
}

retrieveData = async() => {
console.warn('retrievedata')
try {
//await AsyncStorage.multiGet(['id', 'token'], value) -> value([['id', this.state.id], ['token', this.state.token]])
//await AsyncStorage.multiGet([['id'], ['token']]);
await AsyncStorage.multiGet(["id", "token", "sno", "job_title"]).then(response => {
// console.log(response[0][0]) // Key1
if (response !== null) {
// We have data!!
this.setState ({
userId: response[0][1],
userToken: response[1][1]
})
// console.warn('resApi', this.state.userId, this.state.userToken)

        }

       })
    }
        catch (error) {
         // Error retrieving data
       }
       this.ServerAccess()
}

ServerAccess= () => {
   // console.warn('entered',this.letter_no, this.state.userToken)
    fetch("https://beta.piana.in/shakir/staffing/Api/mailerData" , {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'id': this.state.userId,
            'Authorization': this.state.userToken,
            'letter_no':this.letter_no
        },      
    })
.then((response) => response.json())
.then((res) => {
    //console.warn(res)
        this.setState ({
            content: res,
            title: res[0].title,
            htmlContent: res[0].content
            })
       // console.warn('here its',this.state.htmlContent, this.state.title)   
    })

}

componentDidMount() {
this.retrieveData()
//this.ServerAccess()import HTML from 'react-native-render-html';
}

componentWillMount() {
const { navigation } = this.props;
const emailid = navigation.getParam('emailID');
const candName = navigation.getParam('name');
const jobTitle = navigation.getParam('title');
const comp = navigation.getParam('companyName');
const letter_no = navigation.getParam('letter_no')
this.letter_no = letter_no,
this.email = emailid,
this.name = candName,
this.title = jobTitle,
this.companyName = comp
//console.warn('emailTemp', letter_no, jobTitle)
}

render() {
// console.warn('inrender',this.state.htmlContent)
const { width } = Dimensions.get('window');
const data = [
{
heading: ${this.state.title},
content: ${this.state.htmlContent}
},
{
heading: 'Template 2',
content: Dear ${this.name}, \n \n Thank you for applying to the ${this.title} position at ${this.companyName}. \n I鈥檇 like to inform you that we received your application. Our hiring team is currently reviewing all applications and we are planning to schedule interviews in the next two weeks. If you are among qualified candidates, you will receive a call/email from our one of our recruiters to schedule an interview. In any case, we will keep you posted on the status of your application. \n \n Best regards, \n Team HumanPi
},
{
heading: 'Template 3',
content: Dear ${this.name}, \n \n This is regarding the job you have applied for. We want to congratulate you for your selection at the position of ${this.title} at ${this.companyName}. We will get back to you shortly with the joining information. \n \n Best regards, \n Team HumanPi
},
]

// const data = ['Template 1', 'Template 2', 'Template 3' ]
//console.warn('hey', data[0].content)
return (
data={data}
style={{ width:width, maxHeight: 700}}
itemWidth={width - 60}
threshold={80}
contentOffset={12}
renderItem={({ itemIndex, currentIndex, item }) => (
itemIndex={itemIndex}
currentIndex={currentIndex}
easing={Easing.spring}
render={animatedValue => (
style={{ marginTop:30, borderRadius:5, elevation:10, shadowOffset:{width: 1,height: 1}, shadowColor: 'black', shadowOpacity: 1.0, maxWidth: width - 60, height: 550,
transform: [
{
scale: animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [0.9, 1],
extrapolate: 'clamp',
}),
},
],
}}>
title={item.heading} titleStyle={{color:'#fff', fontSize:22, fontWeight:'700' }}>





)}
/>
)}
/>


);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
//paddingTop: 15,
backgroundColor: 'red',
},
pageContainer: {
flex:1,
}
});

_Originally posted by @kanikas24 in https://github.com/archriss/react-native-render-html/issue_comments#issuecomment-453418897_

Most helpful comment

I did this to avoid such a thing
<HTML html={this.state.data.description || '<p></p>'} />

All 5 comments

+1, when html-text too large, error

I had the same mistake. You should get the fetch content ready before render the Page or Screen.
Mi code:

`
axios.get(link)
.then(res => {
let data = res.data.noticia
let noteData = Object.assign ({}, this.state.noteData)
noteData.titulo = data.titulo
noteData.desc_categoria = data.desc_categoria.toUpperCase()
noteData.imagen_principal = data.imagen_principal
noteData.descripcion = data.descripcion
noteData.contenido_nota = data.contenido_nota
noteData.url_nota = data.url_nota

        let date = data.fecha_publicacion.substring(0, 10).split('-')
        let parseDate = date[2] + '/' + date[1] + '/' + date[0]
        let publishTime = new Date(data.fecha_publicacion)
        let time = `${publishTime.getHours() < 10 && '0' + publishTime.getHours()}:${publishTime.getMinutes()}`

            noteData.parseDate = parseDate + '  |  ' + time

        //THIS DOES THE TRICK  :)
        return this.setState({ noteData }, () => this.setState({ contentReady: true }))
        })
        .catch(err => console.log(err))
}

In the render() method:
render(){
let {noteData, contentReady} = this.state
const self = this
const {width, height} = Dimensions.get('window');
const uri = 'https://www.unotv.com'

    return(
        <ScreenContainer>
        {
            //Show loader while the content are load :)
            !contentReady
            ?
            <SkypeIndicator size={85} color="#29aae2" />
            :
            <ScrollView keyboardShouldPersistTaps='always' style={{ flex: 1 }}>
                <View

...
`

Davidcort explained the problem very well. Do not render <HTML .../> until your content is ready. The html prop shouldn't be undefined unless you're rendering remote content.

It also happens when you pass empty string, which is kinda annoying when you have optional data :/ And instead rendering nothing it renders


I did this to avoid such a thing
<HTML html={this.state.data.description || '<p></p>'} />

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chadmorrow picture chadmorrow  路  7Comments

Pradeet picture Pradeet  路  7Comments

duansiyu picture duansiyu  路  4Comments

fahadhaq picture fahadhaq  路  6Comments

Anitorious picture Anitorious  路  7Comments