how to whileText properly

hi guys , i’m building a chat app who display different type of data on the same view (text, image, file, link etc), so i’m using while text to display a style depending on what kind of data it is, and using whiletrue and while false to separate message written by different users. this is what my code looks like

    <ScrollView>
      <StackPanel Alignment="Bottom">
        <Each Items="{MessagesAll}">
          <WhileString  Equals="text" Value="{type}">
            <WhileTrue Value="{dock}">
              <DockPanel Margin="5">
                <Circle Height="40" Width="40" Color="Black" Dock="Left"/>
                <Panel Padding="20" Margin="10,0,10,0">
                  <Rectangle Layer="Background" CornerRadius="10" Opacity=".2" Color="Gray"/>
                  <Text Value="{text}" TextWrapping="Wrap" TextColor="Black" Alignment="CenterLeft" />
                </Panel>
              <AddingAnimation>
                <Scale Factor="0" Duration=".5" Easing="QuinticIn" />
              </AddingAnimation>
              </DockPanel>
            </WhileTrue>
            <WhileFalse Value="{dock}">
              <DockPanel Margin="5">
                <Panel Padding="20" Margin="10,0,10,0">
                  <Rectangle Layer="Background" CornerRadius="10" Opacity=".9" Color="#f15f5f"/>
                  <Text Value="{text}" TextWrapping="Wrap" TextColor="White" Alignment="CenterLeft" />
                </Panel>
              <AddingAnimation>
                <Scale Factor="0" Duration=".5" Easing="QuinticIn" />
              </AddingAnimation>
              </DockPanel>
            </WhileFalse>
          </WhileString>

          <WhileString Equals="image" Value="{type}">
            <WhileTrue Value="{dock}" >
              <DockPanel Margin="5">
                <Panel Padding="20" Margin="10,0,10,0">
                  <Rectangle Layer="Background" CornerRadius="10" Opacity=".12" Color="Green"/>
                  <Rectangle Height="200" Width="99%" CornerRadius="10">
                    <ImageFill Url="{image}" StretchMode="UniformToFill"/>
                  </Rectangle>
                </Panel>
              <AddingAnimation>
                <Scale Factor="0" Duration=".5" Easing="QuinticIn" />
              </AddingAnimation>
              </DockPanel>
            </WhileTrue>

            <WhileFalse Value="{dock}">
              <DockPanel Margin="5">
                <Panel Margin="10,0,10,0">
                  <Rectangle Layer="Background" CornerRadius="10" Opacity=".9" />
                  <Rectangle Height="200" Width="99%" CornerRadius="10">
                    <ImageFill Url="{image}" StretchMode="UniformToFill"/>
                  </Rectangle>
                </Panel>
              <AddingAnimation>
                <Scale Factor="0" Duration=".5" Easing="QuinticIn" />
              </AddingAnimation>
              </DockPanel>
            </WhileFalse>
          </WhileString>
        </Each>
        <LayoutAnimation>
          <Move RelativeTo="PositionChange" Y="1" Duration=".5" Easing="QuinticInOut" />
        </LayoutAnimation>
      </StackPanel>
    </ScrollView>

this is how i’m loading my data

function MessageForm(id, session,  text, createdAt, sender, ParseObject, type, image)
{
  var self = this;
  this.id = id;
  this.session = session;
  this.text = text;
  this.createdAt = createdAt;
  this.sender = sender;
  this.ParseObject= ParseObject;
  this.dock = Observable(function(){
    if(sender == Parse.User.current().id){
      return false
    }else {
      return true
    }
  });
  this.action = Observable(function(){
    if(isDefined(ParseObject.get("action"))){
      return ParseObject.get("action")
    }else {
    }
  });
  this.image = image
  this.type = type;

}

function loadMessage()
{
var query = new Parse.Query("Messages")
query.equalTo("rooms", Parse.User.current().id)
query.find().then(function(results){
  enable.value = false
  MessagesAll.refreshAll(results,
    function(oldItem, newItem){
      return oldItem.id == newItem.id
    },
    function(oldItem, newItem){
      oldItem.createdAt = newItem.get("createdAt")
    },
    function(newItem){
      return new MessageForm(newItem.id, newItem.get("rooms"), newItem.get("text"), newItem.get("createdAt"), newItem.get("sender"), newItem, newItem.get("type"), newItem.get("photo"))
    }
  )
})
}

the problem is when my app doesn’t display the text and the image at the same time.
for displaying the text i need to not download the image, so in my MessageForm function i need to do this.image = image and not this.image = image.url(). for displaying image i need to download the url. both image and text have the same room and are not displayed at the same time

Hi!

I’m not exactly sure whats wrong with your code, but i would suggest you look into using Match & Case for this instead:
https://www.fusetools.com/docs/fuse/reactive/match

Let me know if you get the same issues with that component and i’ll take a closer look to see if there is something else fishy going on :slight_smile:

I finally used match and case .
but the results still the same. i just having this problem with image , others data type works as expected

        <Each Items="{MessagesAll}">
            <Match Value="{type}">
              <Case String="text">
              <WhileTrue Value="{dock}">
                <StackPanel>
                  <DockPanel Margin="5">
                    <Circle Height="40" Width="40" Dock="Left">
                      <ImageFill  Source="LogoAI"/>
                    </Circle>
                    <Panel Padding="20" Margin="10,0,10,0">
                      <Rectangle Layer="Background" CornerRadius="10" Opacity=".2" Color="Gray"/>
                      <Text Value="{text}" TextWrapping="Wrap" TextColor="Black" Alignment="CenterLeft" />
                    </Panel>
                  </DockPanel>
                  <Text Alignment="Right" Margin="0,0,20,0" FontSize="12" Value="{createdAt}"/>

              <AddingAnimation>
                <Scale Factor="0" Duration=".5" Easing="QuinticIn" />
              </AddingAnimation>
                </StackPanel>
              </WhileTrue>
              <WhileFalse Value="{dock}">
                <StackPanel>
                  <DockPanel Margin="5">
                    <Panel Padding="20" Margin="10,0,10,0">
                      <Rectangle Layer="Background" CornerRadius="10" Opacity=".9" Color="#fa3e38"/>
                      <Text Value="{text}" TextWrapping="Wrap" TextColor="White" Alignment="CenterLeft" />
                    </Panel>
                  </DockPanel>

                    <Text Alignment="Right" Margin="0,0,20,0" FontSize="12" Value="{createdAt}"/>

                  <AddingAnimation>
                    <Scale Factor="0" Duration=".5" Easing="QuinticIn" />
                  </AddingAnimation>
                </StackPanel>
              </WhileFalse>
            </Case>
            <Case String="image">
              <StackPanel>
                  <Rectangle Padding="5" Height="140" Width="170" CornerRadius="10">
                    <ImageFill Url="{image}"/>
                  </Rectangle>
              </StackPanel>
            </Case>
            <Case String="QuickChooseYesorNo">
              <StackPanel>
                <Rectangle Height="140" Width="200" Color="Black"/>
              </StackPanel>
            </Case>
            <Case String="rating">

            </Case>
            <Case String="receipt">

            </Case>
            </Match>
        </Each>

Fixed.

i just used different form function for each one of my data type.

function MessageForm(id, session,  text, createdAt, sender, ParseObject, type)
{
  var self = this;
  this.id = id;
  this.session = session;
  this.text = text;
  this.createdAt = moment(createdAt).fromNow();
  this.sender = sender;
  this.ParseObject= ParseObject;
  this.dock = Observable(function(){
    if(sender == Parse.User.current().id){
      return false
    }else {
      return true
    }
  });
  this.type = type;
}

function messageImage(id, session, createdAt, sender, ParseObject, type, image){
  var self = this;
  this.id = id;
  this.session = session;
  this.createdAt = moment(createdAt).fromNow();
  this.sender = sender;
  this.ParseObject = ParseObject;
  this.type = type;
  this.image = image.url()
}

this is how i’m loading datas.

function loadMessage()
{
var query = new Parse.Query("Messages")
query.equalTo("rooms", Parse.User.current().id)
query.find().then(function(results){
  enable.value = false
  if(results.length == 0){
    sendToAPi("starting converse seccour", Parse.User.current().id)
  }else {
    MessagesAll.refreshAll(results,
      function(oldItem, newItem){
        return oldItem.id == newItem.id
      },
      function(oldItem, newItem){
        oldItem.createdAt = newItem.get("createdAt")
      },
      function(newItem){
        if(newItem.length != 0){
          if(newItem.get("type") == "text"){
            return new MessageForm(newItem.id, newItem.get("rooms"), newItem.get("text"), newItem.get("createdAt"), newItem.get("sender"), newItem, newItem.get("type"))
          }else if (newItem.get("type") == "image"){
            return new messageImage(newItem.id, newItem.get("rooms"), newItem.get("createdAt"), newItem.get("sender"), newItem, newItem.get("type"), newItem.get("photo"))
          }else if (newItem.get("type") == "payment"){

          }else if (newItem.get("type") == "quickReply"){

          }else if (newItem.get("type") == "Receipt"){

          }
        }else {
          console.log("haha")
        }
      }
    )
  }
})
}

Good that you got it working :smiley: