Dynamics 365 Dynamics NAV 2017 Extensions

Build a PowerApp – Add Images Part2

This is the second part of the Build a PowerApp. In the last blog, I explained how you can create a simple app from a Odata connection. Link to Part 1

This part will focus on how we can sync Item Pictures from NAV to the PowerApps.

Limitation: Since NAV stores images in MediaSet/Media type we cannot pass them through Odata webservices (which is what the Dynamics NAV Connector uses).

Workaround: Convert NAV images to base64 and send them to image storage service. Capture the direct link of the images and store them in a field on Item table. Pass that field to PowerApp through Odata. PowerApp will then recognize the image URL and display the images.

Note: I have added a field in Item table and Item list page. You can avoid that by creating a new table and page with 1-1 relation with Item. Then either create a query combining both tables and expose as webservice or simply add another data source in PowerApp and handle the relation logic in there

To do this I used Imgur API to store images from NAV. You need to register at imgur and create a new Application ID here. To know more about how to use the upload API, please refer to the docs here.

Steps:

  1. Create a new field in Item Table to capture Direct URLs of Images.
  1. Add the new field on Item Card.

  1. Save the objects.
  2. Create a new codeunit or Import it after downloading from here. Create a new function.

Make sure to replace the Client ID with your own client id that you will receive after registration

CODE:

 

LOCAL PostImageToImgur(PictureInBase64 : BigText) : Text

PostUrl := 'https://api.imgur.com/3/image';

HttpClient := HttpClient.HttpClient();

HttpClient.BaseAddress := Uri.Uri(PostUrl);

stringcontent :=stringcontent.StringContent('{"image":"'+FORMAT(PictureInBase64)+'"}',encoding.UTF8,'application/json');

HttpContent:=stringcontent;

HttpClient.DefaultRequestHeaders.Add('Authorization','Client-ID <Your Imgur client ID>');

HttpResponseMessage := HttpClient.PostAsync('',HttpContent).Result;

HttpResponseMessage.EnsureSuccessStatusCode;

result := HttpResponseMessage.Content.ReadAsStringAsync.Result;

JObject := JObject.Parse(result.ToString);

IF (JObject.GetValue('success').ToString)='True' THEN BEGIN

Json := JObject.GetValue('data').ToString;

JObject2 := JObject2.Parse(Json);

EXIT(JObject2.GetValue('link').ToString);

END ELSE

EXIT('error');

Local Variables:

Parameters

Return Value

  1. Create two subscribers functions to handle User uploading a image to Item card or Taking an image by mobile device.

 

Code: 

[EventSubscriber] ItemPictureOnActionImport(VAR Rec : Record Item)

 IF (Rec.Picture.COUNT >= 1)

 THEN BEGIN

 CLEAR(BigPictureText);

 TempBlob.INIT;

 MediaGuid:=Rec.Picture.ITEM(1);

 TenantMedia.GET(MediaGuid);

 TenantMedia.CALCFIELDS(Content);

 TempBlob.Blob:=TenantMedia.Content;

 BigPictureText.ADDTEXT(TempBlob.ToBase64String);

 Rec."Picture url":=PostImageToImgur(BigPictureText);

 Rec.MODIFY;

 MESSAGE('Sent to Imgur');

 END



[EventSubscriber] ItemPictureOnActionTake(VAR Rec : Record Item)

 IF (Rec.Picture.COUNT >= 1)

 THEN BEGIN

 CLEAR(BigPictureText);

 TempBlob.INIT;

 MediaGuid:=Rec.Picture.ITEM(1);

 TenantMedia.GET(MediaGuid);

 TenantMedia.CALCFIELDS(Content);

 TempBlob.Blob:=TenantMedia.Content;

 BigPictureText.ADDTEXT(TempBlob.ToBase64String);

 Rec."Picture url":=PostImageToImgur(BigPictureText);

 Rec.MODIFY;

 MESSAGE('Sent to Imgur');

 END

Properties:

ItemPictureOnActionImport

ItemPictureOnActionTake

 

Variables (same for both subscribers)

  1. So we have handled new pictures that will be uploaded by users but what about the pictures that are already there.

For that you can run a bulk function once for your DB.

Code:

LOCAL BulkItemPictureUpload()

IF Item.FINDFIRST THEN

 REPEAT

 IF (Item.Picture.COUNT >= 1)

 THEN BEGIN

 TempBlob.INIT;

 MediaGuid:=Item.Picture.ITEM(1);

 TenantMedia.GET(MediaGuid);

 TenantMedia.CALCFIELDS(Content);

 TempBlob.Blob:=TenantMedia.Content;

 BigPictureText.ADDTEXT(TempBlob.ToBase64String);

 Item."Picture url":=PostImageToImgur(BigPictureText);

 Item.MODIFY;

 CLEAR(BigPictureText);

 END

 UNTIL

 Item.NEXT=0;

 MESSAGE('completed');

Now all your images are uploaded to imgur and can be shown in PowerApps

 

  1. Open PowerApps web portal again. Refresh the data source so that Picture URL get populated.
  2. Select an image and change data property to Picture_url

  1. Pictures will be automatically populated.
  2. The App is created with Pictures from NAV.

In an upcoming blog, I will try and see if we can make this integration two way. Adding ability to edit item details in the app which will sync back to NAV.

 

 

 

 

 

 

 

 

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *