Weird path error when databinding to FileSource type property

Hi,

I’m using version 0.21 on Mac OSX. In the following code, I have a MenuGrid class which has a property of type FileSource. When I use this class by setting the ImageFileSource property explicitly it works. But when I make databinding I get weird path error:

<Panel>
  <JavaScript>
    var Observable = require('FuseJS/Observable');

    var menuItems = [{
      "title": "Menu Item 01",
      "iconFileName": "../../assets/icons/Like.png"
    }, {
      "title": "Menu Item 02",
      "iconFileName": "../../assets/icons/Rules.png"
    }, {
      "title": "Menu Item 03",
      "iconFileName": "../../assets/icons/Share.png"
    }];

    function clone(obj) {
      return JSON.parse(JSON.stringify(obj));
    }

    function getMenuItems() {
      return clone(menuItems);
    }

    exports.menuItems = getMenuItems(); 
  </JavaScript>

  <Grid ux:Class="MenuGrid" Background="White" Columns="3*,7*" ColumnCount="3" Padding="20,30">
    <Uno.UX.FileSource ux:Property="ImageFileSource" />
    <string ux:Property="MenuText" />

    <Image File="{Property this.ImageFileSource}" Alignment="Left" Width="56" Height="56"/>
    <Text FontSize="16" Margin="15,0,0,0" Alignment="CenterLeft" TextAlignment="Right" TextWrapping="Wrap" Value="{Property this.MenuText}" />
  </Grid>

  <!-- This is working -->
<!-- 
  <StackPanel>
    <MenuGrid Margin="0,10,0,0" ImageFileSource="../../assets/icons/Like.png" MenuText="Menu Item 01" />
    <MenuGrid Margin="0,10,0,0" ImageFileSource="../../assets/icons/Rules.png" MenuText="Menu Item 02" />
    <MenuGrid Margin="0,10,0,0" ImageFileSource="../../assets/icons/Share.png" MenuText="Menu Item 03" />
  </StackPanel>
 -->

  <!-- This is NOT working. It gives ERROR! -->
  <StackPanel>
    <Each Items="{menuItems}">
      <MenuGrid Margin="0,10,0,0" MenuText="{title}" ImageFileSource="{iconFileName}"  />
    </Each>
  </StackPanel>

</Panel>

And here is the error that I get when I use databinding:

ERROR: Could not find a part of the path "/Applications/Sublime Text.app/Contents/MacOS/assets/icons/Like.png".

Is it a bug or am I missing something?

Thanks in advance,

Ipek

When a Fuse project is compiled, we detect that you have ImageFileSource="../../assets/icons/Like.png" in your project, and copy that file to the app. However, when you do this dynamically from JavaScript, there is no way to statically detect this, so you have to let Fuse know about your files.

Try adding "../../Assets/*:Bundle" to the Includes section of your .unoproj.

Here is a small example:

.unoproj:

{
  "RootNamespace":"",
  "Packages": [
    "Fuse",
    "FuseJS"
  ],
  "Includes": [
    "",
    "Assets/:Bundle"
  ]
}

MainView.ux:

<App>
    <ClientPanel>
        <JavaScript>
            module.exports = {logo:"Assets/FuseLogo2.png"}
        </JavaScript>
        <StackPanel>
            <Image File="Assets/FuseLogo.png" Color="#000"/>
            <Image File="{logo}" Color="#000"/>
        </StackPanel>
    </ClientPanel>
</App>

Thanks for the reply Anders,

Now I understand the problem. But you may want to now that adding ../../Assets/*:Bundle to the Includes section the .unoproj file gives the following error during build:

FATAL ERROR: System.FormatException: '..' is not valid in glob pattern
  at Uno.ProjectFormat.GlobList.Add (System.String dir, System.String pattern, Uno.Source src, IncludeItemType type, System.String cond) [0x00054] in /Users/outracks/buildAgent1/work/397767071b813b09/Source/Engine/Uno.ProjectFormat/GlobList.cs:26 
  at Uno.ProjectFormat.IncludeGlobber.FindItems (IEnumerable`1 includes, IEnumerable`1 excludes, Boolean throwOnError, Boolean excludeItems) [0x0023a] in /Users/outracks/buildAgent1/work/397767071b813b09/Source/Engine/Uno.ProjectFormat/IncludeGlobber.cs:104 
  at Uno.ProjectFormat.IncludeGlobber.FindItems (Uno.ProjectFormat.Project project, IEnumerable`1 includes, IEnumerable`1 excludes, System.Collections.Generic.List`1 result, Uno.Logging.Log log, Boolean throwOnError, Boolean excludeItems) [0x00000] in /Users/outracks/buildAgent1/work/397767071b813b09/Source/Engine/Uno.ProjectFormat/IncludeGlobber.cs:22 
  at Uno.ProjectFormat.Project.GetFlattenedItems (Uno.Logging.Log log, Boolean force) [0x0001c] in /Users/outracks/buildAgent1/work/397767071b813b09/Source/Engine/Uno.ProjectFormat/Project.cs:203 
  at Uno.ProjectFormat.Project.get_AdditionalFiles () [0x00000] in <filename unknown>:0 
  at Uno.ProjectFormat.Project.CreateSourcePackage (Boolean isStartup) [0x0004d] in /Users/outracks/buildAgent1/work/397767071b813b09/Source/Engine/Uno.ProjectFormat/Project.cs:381 
  at Uno.Build.Packages.PackageResolver.Configure () [0x00000] in <filename unknown>:0 
  at Uno.Build.ProjectBuilder.Build_inner (Uno.ProjectFormat.Project project) [0x00000] in <filename unknown>:0

Instead I added "assets/icons/*:Bundle" to the .unoproj file and removed relative path strings from the menuItems array and it worked! I always thought that "assets/*:Bundle" was also including subdirectories and I learned that it’s not :slight_smile:

.unoproj:

{
  "RootNamespace":"",
  "Packages": [
      "Fuse",
      "FuseJS"
  ],
  "Includes": [
    "*",
    "assets/*:Bundle",
    "assets/icons/*:Bundle"
  ]
}

MainView.ux:

<Panel>
  <JavaScript>
    var Observable = require('FuseJS/Observable');

    var menuItems = [{
      "title": "Menu Item 01",
      "iconFileName": "assets/icons/Like.png"
    }, {
      "title": "Menu Item 02",
      "iconFileName": "assets/icons/Rules.png"
    }, {
      "title": "Menu Item 03",
      "iconFileName": "assets/icons/Share.png"
    }];

    function clone(obj) {
      return JSON.parse(JSON.stringify(obj));
    }

    function getMenuItems() {
      return clone(menuItems);
    }

    exports.menuItems = getMenuItems(); 
  </JavaScript>

  <Grid ux:Class="MenuGrid" Background="White" Columns="3*,7*" ColumnCount="3" Padding="20,30">
    <Uno.UX.FileSource ux:Property="ImageFileSource" />
    <string ux:Property="MenuText" />

    <Image File="{Property this.ImageFileSource}" Alignment="Left" Width="56" Height="56"/>
    <Text FontSize="16" Margin="15,0,0,0" Alignment="CenterLeft" TextAlignment="Right" TextWrapping="Wrap" Value="{Property this.MenuText}" />
  </Grid>

  <!-- This is working -->
<!-- 
  <StackPanel>
    <MenuGrid Margin="0,10,0,0" ImageFileSource="../../assets/icons/Like.png" MenuText="Menu Item 01" />
    <MenuGrid Margin="0,10,0,0" ImageFileSource="../../assets/icons/Rules.png" MenuText="Menu Item 02" />
    <MenuGrid Margin="0,10,0,0" ImageFileSource="../../assets/icons/Share.png" MenuText="Menu Item 03" />
  </StackPanel>
 -->

  <!-- This also NOW WORKS :)) -->
  <StackPanel>
    <Each Items="{menuItems}">
      <MenuGrid Margin="0,10,0,0" MenuText="{title}" ImageFileSource="{iconFileName}"  />
    </Each>
  </StackPanel>

</Panel>

Thanks again

Great! Good to hear you got it working. I had to guess a bit with the paths there as I didn’t have your full project. :slight_smile: