Pluggable widget not updating value from props

0
Hi All, I am creating a pluggable widget, and I am struggling to get the display value to update based on the input attribute provided to the widget. If any one could help me out it would be much appreciated. See full widget code below : Main Component import { React,Component ,createElement} from "react"; import CircularProgress from "./components/CircleComponent"; export class CircularProgressBar extends Component {          constructor(props){         super(props);         const {progress} = this.props;         console.log('constructor triggered');     }       render() {         const {progress} = this.props;         console.log('render triggered');         return (             <CircularProgress                  progress={progress.value}                  size={200}             />         )     } }     Child Component   import React, { useRef, useEffect, createElement } from "react"; import styled from 'styled-components/native'; import {Animated} from 'react-native'; const EmptyColour = '#a0a0a1';  const ProgressColour = '#0085ff';   const CircleBase = styled(Animated.View)` width: ${props => props.size}px; height: ${props => props.size}px; border-radius: ${props => props.size / 2}px; border-width: ${props => props.size / 10}px; `; const EmptyCircle = styled(CircleBase)`     border-color: ${EmptyColour};     justify-content:center;     align-items: center;     transform: rotate(-45deg); `; const Indicator = styled(CircleBase)`     position: absolute;     border-left-color:${ProgressColour};     border-top-color:${ProgressColour};     border-bottom-color:transparent;     border-right-color:transparent; `; const CoverIndicator = styled(CircleBase)`     position: absolute;     border-left-color:${EmptyColour};     border-top-color:${EmptyColour};     border-bottom-color:transparent;     border-right-color:transparent; `; export default function CircularProgress(props) { //added input props     const {progress, size} = this.props //destructured the props     console.log (styled)     const animatedProgress = useRef(new Animated.Value(0)).current;        const animateProgress = useRef(toValue => {       Animated.spring(animatedProgress, {         toValue,         useNativeDriver: true,       }).start();     }).current;        useEffect(() => {       animateProgress(progress);     }, [animateProgress,progress]);        const firstIndicatorRotate = animatedProgress.interpolate({       inputRange: [0, 50],       outputRange: ['0deg', '180deg'],       extrapolate: 'clamp',     });        const secondIndicatorRotate = animatedProgress.interpolate({       inputRange: [0, 100],       outputRange: ['0deg', '360deg'],       extrapolate: 'clamp',     });        const secondIndictorVisibility = animatedProgress.interpolate({       inputRange: [0, 49, 50, 100],       outputRange: [0, 0, 1, 1],       extrapolate: 'clamp',     });        return (        <EmptyCircle size={size}>          <Indicator           style={{transform: [{rotate: firstIndicatorRotate}]}}           size={size}         />         <CoverIndicator size={size} />         <Indicator           size={size}           style={{             transform: [{rotate: secondIndicatorRotate}],             opacity: secondIndictorVisibility,           }}         />       </EmptyCircle>     );   }   Widget XML   <?xml version="1.0" encoding="utf-8"?> <widget id="mendix.circularprogressbar.CircularProgressBar" needsEntityContext="true" offlineCapable="true" pluginWidget="true"         supportedPlatform="Native" xmlns="http://www.mendix.com/widget/1.0/"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://www.mendix.com/widget/1.0/ ../node_modules/mendix/custom_widget.xsd">     <name>Circular Progress Bar</name>     <description>Animated Circle Progress widget</description>     <icon>         iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABp1BMVEUAAABV//9mzP9LtP9Ms/9Jtv9NsvdJsfpLtPpJsfdJsfhJsvhJsvdKsvdJsPhKsPhJsfdJsPhJsfdIsfhJsfdIsPdJsfhJsfhJsPhJsPhIsfhIsPdJsPdKsPdKsfdNsvdOsvdPs/dQs/dRtPdStPdTtPdUtfdWtvdXtvdauPdcuPdeufdeufhguvhiu/hju/hkvPhmvfhnvfhpvvhrv/huwPhvwfhxwfhywvhzwvh4xfl5xfl6xfl8xvl9xvl9x/mByPmCyfmFyvmGyvmJzPmKzPmLzfmNzvqPzvqQz/qT0PqU0PqU0fqX0vqY0vqa0/qe1fqg1vqj1/uk1/un2fup2vut2/uv3Puw3Puw3fuz3vu13/u23/u34Pu44Pu64fu64fy84vy94vy+4/y/4/zD5fzE5fzG5vzH5vzI5/zK6PzL6PzR6/zT7P3U7P3V7f3W7f3Y7v3Z7v3c8P3e8f3f8f3g8f3i8v3l8/3l9P3n9P3r9v7t9/7u9/7v+P7w+P7x+f7y+f70+v71+v74/P75/P76/f77/f78/f78/v79/v7+/v7////6dMsRAAAAG3RSTlMAAwURGxwhMTNic3SEh4iVp7XBzejt7vH5/f6PsMNWAAABsklEQVR4AWIYfGAUjIJRMAqYuYREJKWJAqLCPGwY+jnFpEkBEryMqPr5pEkFgkwo9kuTDviR/S9GhgFSHAgDuKXJAQIIA4TIMkAcEY4i0mQBVrgBkuQZwA43QJo8wIFhQEhEOIBQOutHJozDOP5Crp4e1RhkJ0tKGJFd6oNEdtmJyEIzpaZl5nrRZgaHM/2Pf5/vwXXfyagXgG93bwSAlEolowLMm9w83gibhXH2gKKVdD67gTnWjwCk+VVjMQS4suSnnjMLRVFc9sAHvAX2A9fySaXNBMbEZVUWscaHIMRuqwBgD8hDEbnsRmfjUKJkAQZGCTlO/xWBwIADQLIZBlY441MvfoF1xlFS/4fy+bzXKh4dgNJE7L3eh3tmtuWa+AMcMIY3dgUvZQpGEYmMw2kD7HC+R29UqyoXLaBd0QZxzgXgikLLDSqJTKU5HOcS0MsbA9jPqtwCRvXm2eorBbNIJBw3KJ9O4Yl+AAXdnyaLt7PWN3jRWLvzmAVp94zO5+n41/onfo/UpExxZqI0O7NQr0DhIq9Io7hQpbRYp7hiobRqo6ByFcNWuY6CUTAKRgEAo8X0lBD3V30AAAAASUVORK5CYII=     </icon>     <properties>         <propertyGroup caption="General">             <property key="progress" type="attribute" required="true">                 <caption>Progress Indicator</caption>                 <description>The attribute that contains the circularprogressbar value, should be an integer between 0 and 100</description>                 <attributeTypes>                     <attributeType name="Integer"/>                 </attributeTypes>             </property>         </propertyGroup>     </properties> </widget>  
asked
3 answers
4

i just figure it out:

 

at main component

 

you need to do 

 

const CircularProgressBar  = ({progress}) => {

 

useEffect(() => {

// do something when the progress is changed

},[progress])

 

return (progress ? 

<CircularProgress 

                progress={progress.value} 

                size={200}

            /> : 

<CircularProgress 

                progress={null} 

                size={200}

            />

}

 

export default CircularProgressBar ;

answered
1

Hi Ryan,

Your props are an array and in your case only one prop is available there, progress. To read this value you need to use this.props.progress.value. In your example above it seems with your redefined variables you are feeding this.props.value, which isn’t a property if I look at your XML.

 

Just skip redefining and directly feed this.props.progress.value to the React CircularProgress component.

answered
0

Hey Everyone,

 

Forgot to update this post with my solution, but thanks to all who answered.

My final code for this widget ended up being as follows :

Main component :

import { React,Component ,createElement} from "react";
import CircularProgress from "./components/CircleComponent";
import styled from 'styled-components/native';

const Container = styled.View`
  flex: 1;
  align-items: center;
  justify-content: center;
  overflow: hidden;
`;

export class CircularProgressBar extends Component {
    constructor(props){
        super(props);
        console.log('constuctor triggered');
    }
  
    render() {
        console.log('render triggered');
        return (
            <Container>
                <CircularProgress 
                    progress={Number(this.props.progress.value)} 
                    size={230}
                />
            </Container>
        )
    }
}

 

Child Component :

import React, { useRef, useEffect, createElement } from "react";
import styled from 'styled-components/native';
import {Animated} from 'react-native';

const EmptyColour = '#a0a0a1'; //changed this border color
const ProgressColour = '#0085ff';


const CircleBase = styled(Animated.View)`
width: ${props => props.size}px;
height: ${props => props.size}px;
border-radius: ${props => props.size / 2}px;
border-width: ${props => props.size / 10}px;
`;

const EmptyCircle = styled(CircleBase)`
    border-color: ${EmptyColour};
    justify-content:center;
    align-items: center;
    transform: rotate(-45deg);
`;

const Indicator = styled(CircleBase)`
    position: absolute;
    border-left-color:${ProgressColour};
    border-top-color:${ProgressColour};
    border-bottom-color:transparent;
    border-right-color:transparent;
`;

const CoverIndicator = styled(CircleBase)`
    position: absolute;
    border-left-color:${EmptyColour};
    border-top-color:${EmptyColour};
    border-bottom-color:transparent;
    border-right-color:transparent;
`;


export default function CircularProgress(props) { //added input props

    const {progress, size} = props //destructured the props
    console.log (styled)
    const animatedProgress = useRef(new Animated.Value(0)).current;
  
    const animateProgress = useRef(toValue => {
      Animated.spring(animatedProgress, {
        toValue,
        useNativeDriver: true,
      }).start();
    }).current;
  
    useEffect(() => {
      animateProgress(progress);
    }, [animateProgress, progress]);
  
    const firstIndicatorRotate = animatedProgress.interpolate({
      inputRange: [0, 50],
      outputRange: ['0deg', '180deg'],
      extrapolate: 'clamp',
    });
  
    const secondIndicatorRotate = animatedProgress.interpolate({
      inputRange: [0, 100],
      outputRange: ['0deg', '360deg'],
      extrapolate: 'clamp',
    });
  
    const secondIndictorVisibility = animatedProgress.interpolate({
      inputRange: [0, 49, 50, 100],
      outputRange: [0, 0, 1, 1],
      extrapolate: 'clamp',
    });
  
    return ( //Added size prop to each component
      <EmptyCircle size={size}> 
        <Indicator
          style={{transform: [{rotate: firstIndicatorRotate}]}}
          size={size}
        />
        <CoverIndicator size={size} />
        <Indicator
          size={size}
          style={{
            transform: [{rotate: secondIndicatorRotate}],
            opacity: secondIndictorVisibility,
          }}
        />
      </EmptyCircle>
    );
  }

    

And my widget XML :
 

<?xml version="1.0" encoding="utf-8"?>
<widget id="mendix.circularprogressbar.CircularProgressBar" needsEntityContext="true" offlineCapable="true" pluginWidget="true"
        supportedPlatform="Native" xmlns="http://www.mendix.com/widget/1.0/"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.mendix.com/widget/1.0/ ../node_modules/mendix/custom_widget.xsd">
    <name>Circular Progress Bar</name>
    <description>Animated Circle Progress widget</description>
    <icon>
        iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABp1BMVEUAAABV//9mzP9LtP9Ms/9Jtv9NsvdJsfpLtPpJsfdJsfhJsvhJsvdKsvdJsPhKsPhJsfdJsPhJsfdIsfhJsfdIsPdJsfhJsfhJsPhJsPhIsfhIsPdJsPdKsPdKsfdNsvdOsvdPs/dQs/dRtPdStPdTtPdUtfdWtvdXtvdauPdcuPdeufdeufhguvhiu/hju/hkvPhmvfhnvfhpvvhrv/huwPhvwfhxwfhywvhzwvh4xfl5xfl6xfl8xvl9xvl9x/mByPmCyfmFyvmGyvmJzPmKzPmLzfmNzvqPzvqQz/qT0PqU0PqU0fqX0vqY0vqa0/qe1fqg1vqj1/uk1/un2fup2vut2/uv3Puw3Puw3fuz3vu13/u23/u34Pu44Pu64fu64fy84vy94vy+4/y/4/zD5fzE5fzG5vzH5vzI5/zK6PzL6PzR6/zT7P3U7P3V7f3W7f3Y7v3Z7v3c8P3e8f3f8f3g8f3i8v3l8/3l9P3n9P3r9v7t9/7u9/7v+P7w+P7x+f7y+f70+v71+v74/P75/P76/f77/f78/f78/v79/v7+/v7////6dMsRAAAAG3RSTlMAAwURGxwhMTNic3SEh4iVp7XBzejt7vH5/f6PsMNWAAABsklEQVR4AWIYfGAUjIJRMAqYuYREJKWJAqLCPGwY+jnFpEkBEryMqPr5pEkFgkwo9kuTDviR/S9GhgFSHAgDuKXJAQIIA4TIMkAcEY4i0mQBVrgBkuQZwA43QJo8wIFhQEhEOIBQOutHJozDOP5Crp4e1RhkJ0tKGJFd6oNEdtmJyEIzpaZl5nrRZgaHM/2Pf5/vwXXfyagXgG93bwSAlEolowLMm9w83gibhXH2gKKVdD67gTnWjwCk+VVjMQS4suSnnjMLRVFc9sAHvAX2A9fySaXNBMbEZVUWscaHIMRuqwBgD8hDEbnsRmfjUKJkAQZGCTlO/xWBwIADQLIZBlY441MvfoF1xlFS/4fy+bzXKh4dgNJE7L3eh3tmtuWa+AMcMIY3dgUvZQpGEYmMw2kD7HC+R29UqyoXLaBd0QZxzgXgikLLDSqJTKU5HOcS0MsbA9jPqtwCRvXm2eorBbNIJBw3KJ9O4Yl+AAXdnyaLt7PWN3jRWLvzmAVp94zO5+n41/onfo/UpExxZqI0O7NQr0DhIq9Io7hQpbRYp7hiobRqo6ByFcNWuY6CUTAKRgEAo8X0lBD3V30AAAAASUVORK5CYII=
    </icon>
    <properties>
        <propertyGroup caption="General">
            <property key="progress" type="attribute" required="true">
                <caption>Progress Indicator</caption>
                <description>The attribute that contains the circularprogressbar value, should be an integer between 0 and 100</description>
                <attributeTypes>
                    <attributeType name="Integer"/>
                </attributeTypes>
            </property>
        </propertyGroup>
    </properties>
</widget>

 

answered