Community Tip - Need to share some code when posting a question or reply? Make sure to use the "Insert code sample" menu option. Learn more! X
Hi all,
I have some JSON dataset in Thingworx repository. I'm looking for a way to download and use it in experience runtime. Could any one help me with this.
Thanks in advance.
/VR
Solved! Go to Solution.
Yes this seems to be difficult to achieve. I think in your code is a problem with passing arguments between the call of the service and the event. It is correctly as your mentionded that this is asynchronous call – but nearly all calls in JavaScript are asynchronous calls. The $broadcast works asynchronously and will not return any values and there is no way to pass e.g. the key argument to the event LoadJSON-complete.
Also, I want to point that to define the event listener inside the forEach loop is definitely not a good idea. The event listener should be defined globally.
So I fixed the code and called the broadcast /also alternate call is twx.app.fn.triggerDataService (better) / - called the service in a loop for each key/value pair from the json list . So all calls are executed immediately (as expected) - An then after some time the events are fired- but there seems to be something a twx srv cache issue - so it seems to forget the other call - when we have more than 2 or 3 call so it did not emit the events for all calls.
To the question - how to make synchronous - I do not think that it is possible here. In generally we can use some promise approach but here we have an array as results and it will be difficult to manage the different items
For me seems that the best approach is to use some recursive call principle -
call - event completed - next call etc....
The following code was working fine in my example:
// $scope, $element, $attrs, $injector, $sce, $timeout, $http, $ionicPopup, and $ionicPopover services are available
$scope.modelDataDynamic=[];
$scope.COUNT=0;
var MODEL_JSON = {
'model-1-a': 'a.json',
'model-1-b': 'b.json',
'model-1-c': 'c.json',
'model-1-d': 'd.json',
'model-1-e': 'e.json',
'model-1-f': 'f.json',
}
//load MODEL_JSON files
console.log('load MODEL_JSON files');
//==================================================
//==================================================
angular.element(document).ready(function () {
console.log("Register the LoadJson-Complete");
//==== LoadJSON COMPLETE
$scope.$root.$on('LoadJSON-complete', function (event, args) {
console.log("LoadJSON-complete event");
//will print to console the event name - LoadJSON-Complete
console.log("name=" + event.name)
// the data was the event returns
$scope.modelDataDynamic[$scope.COUNT].jsonData = args.data;
//print to the console to check the data
console.log(JSON.stringify($scope.modelDataDynamic[$scope.COUNT].jsonData))
// debugging inof
console.log("key=" +$scope.modelDataDynamic[$scope.COUNT].key+";value="
+ $scope.modelDataDynamic[$scope.COUNT].value + ";COUNT="+$scope.COUNT+
"length="+$scope.modelDataDynamic.length);
// this a double check we will convert it to string and parse it back to json
//this will ensure that data is correct and has the correct syntax
if( ++$scope.COUNT > $scope.modelDataDynamic.length-1)
{//finished
$scope.finished();
}
else
{$timeout($scope.GetJsonFromTwxRepository('/test/jsons/'
+ $scope.modelDataDynamic[$scope.COUNT].value),500,true)
}
});
})
//===================================================
//==================================================
$scope.GetJsonFromTwxRepository = function (path) {
console.log("$scope.GetJsonFromTwxRepository(path="+path+") ");
$timeout(function () {
// $rootScope.$broadcast('app.mdl.TestRepository.svc.LoadJSON',
twx.app.fn.triggerDataService('TestRepository','LoadJSON',
{"path": path});}
, 5,true);
console.log("after call of GetJsonFromTwxRepository")
};
//==================================================
//==================================================
$scope.$on('$ionicView.afterEnter', function () {
console.log("$ionicView.afterEnter was called ");
console.log('Calling now the service in a loop');
$scope.COUNT=0;
angular.forEach(MODEL_JSON, function (value, key) {
console.log("calling angular.forEach value="+value+ " key="+key);
let temp_obj= {}
temp_obj.key=key
temp_obj.value=value
$scope.modelDataDynamic.push(temp_obj) })
$timeout(()=>{
$scope.GetJsonFromTwxRepository('/test/jsons/' +$scope.modelDataDynamic[$scope.COUNT].value)
$scope.$applyAsync();
},100,true)
})
//=======================$scope.finished();=========
//==================================================
//$scope.$watch('COUNT', function (newValue, oldValue, scope) {
//if(scope.app.params.SVC_CALL_NUM <1)
$scope.finished=function(){
console.warn("completed the loop");
let a = $scope.modelDataDynamic
for (var i in a)
{ console.log("here Json for $scope.modelDataDynamic["+i+"]")
console.log("key="+ a[i].key + " value="+a[i].value)
console.log("==============================================")
console.log(JSON.stringify(a[i].jsonData));
console.log("==============================================")
}
$timeout( function() { console.warn($scope.modelDataDynamic);}, 1000)
}
So when tested I was working fine with the following print:
Hello,
Did you have a look to this post ?
I think it is a good start about how to download a file.
To read it, I think that it is possible to store json data into a variable in javascript.
Best regards,
Samuel
Hi @sdidier
I tried method mentioned in that post but I'm not able to read json value in runtime.
/VR
"was not able to read at runtime" - means it works in preview but not on mobile or both not working in preview and not working on Mobile plattfrom?
Thanks, so I asked this question because , when it work in preview it still could not work on mobile device - but in this case is issue based on permission setting of the used method.
1.)To the current issue - let say you have a repository thing named "CAD-Files-Repository"
//////////////////////////////////////////////////////////////
$scope.GetJsonFromTwxRepository = function(path) {
$scope.$applyAsync(function() {
$rootScope.$broadcast('app.mdl.CAD-Files-Repository.svc.LoadJSON',
{"path":path}
);} ,500 );
console.log("after call of GetJsonFromTwxRepository")
};
////////////////////////////////////////////////////////////
Here is important the service string- in my example it is 'app.mdl.CAD-Files-Repository.svc.LoadJSON' where the Thingworx thing 'CAD-Files-Repository' - in case that your repository is named MyRepository1 - then the string should be 'app.mdl.MyRepository1.svc.LoadJSON' .
2.) another point is that you need to add the service LoadJSON of your repository thing to the External data section:
3.) you need also to define the method which will return the results of the Json. Please, pay attention that the call of the broadcast service will start the twx service but will not return any values from it. When the twx service complete it will emit an event to trigger this event we can use some code like this:
$scope.$on('$ionicView.afterEnter',function(){
console.log("$ionicView.afterEnter was called ");
$scope.$root.$on('LoadJSON-complete', function(event, args) {
console.log("LoadJSON-complete event");
//will print to console the event name - LoadJSON-Complete
console.log("name="+event.name)
console.warn(args.data);// the data was the event returns
$scope.COMP_LOCs=args.data // here we will set the data to global vars
console.log(JSON.stringify( $scope.COMP_LOCs))//print to the console to check the data
let json_new_obj=JSON.parse(JSON.stringify( $scope.COMP_LOCs))
// this a double check we will convert it to string and parse it back to json
//this will ensure that data is correct and has the correct syntax
});
}) //event: when 2d View loaded
So when the event is called it will set the global variable - here $scope.COMP_LOCs which you can use later to read the json or different subparts of it.
Thanks for the code it works fine. When I try to execute Thingworx service in a loop, output of the service is not varying/wrong. Looks like function 'GetJSONfromTWXRepository' is running in async mode. How we can make this is as synchronous one.
PFB code for reference:
var MODEL_JSON = {
'model-1-a': 'a.json',
'model-1-b': 'b.json'
}
//load MODEL_JSON files
console.log('load MODEL_JSON files');
// $scope, $element, $attrs, $injector, $sce, $timeout, $http, $ionicPopup, and $ionicPopover services are available
$scope.GetJsonFromTwxRepository = function (path) {
$scope.$applyAsync(function () {
$rootScope.$broadcast('app.mdl.SystemRepository.svc.LoadJSON',
{
"path": path
}
);
}
, 500);
console.log("after call of GetJsonFromTwxRepository")
};
$scope.modelDataDynamic = [];
$scope.$on('$ionicView.afterEnter', function () {
console.log('Calling service');
angular.forEach(MODEL_JSON, function (value, key) {
$scope.GetJsonFromTwxRepository('/' + value);
console.log(value);
console.log("$ionicView.afterEnter was called ");
$scope.$root.$on('LoadJSON-complete', function (event, args) {
console.log("LoadJSON-complete event");
//will print to console the event name - LoadJSON-Complete
console.log("name=" + event.name)
console.log(event);
console.warn(args.data);
// the data was the event returns
$scope.COMP_LOCs = args.data // here we will set the data to global vars
console.log(JSON.stringify($scope.COMP_LOCs))//print to the console to check the data
$scope.modelDataDynamic[key] = args.data;
// this a double check we will convert it to string and parse it back to json
//this will ensure that data is correct and has the correct syntax
}
);
});
}
)
console.log($scope.modelDataDynamic);
modelDataDynamic output is same for both key. How we can over come this ?
/VR
Yes this seems to be difficult to achieve. I think in your code is a problem with passing arguments between the call of the service and the event. It is correctly as your mentionded that this is asynchronous call – but nearly all calls in JavaScript are asynchronous calls. The $broadcast works asynchronously and will not return any values and there is no way to pass e.g. the key argument to the event LoadJSON-complete.
Also, I want to point that to define the event listener inside the forEach loop is definitely not a good idea. The event listener should be defined globally.
So I fixed the code and called the broadcast /also alternate call is twx.app.fn.triggerDataService (better) / - called the service in a loop for each key/value pair from the json list . So all calls are executed immediately (as expected) - An then after some time the events are fired- but there seems to be something a twx srv cache issue - so it seems to forget the other call - when we have more than 2 or 3 call so it did not emit the events for all calls.
To the question - how to make synchronous - I do not think that it is possible here. In generally we can use some promise approach but here we have an array as results and it will be difficult to manage the different items
For me seems that the best approach is to use some recursive call principle -
call - event completed - next call etc....
The following code was working fine in my example:
// $scope, $element, $attrs, $injector, $sce, $timeout, $http, $ionicPopup, and $ionicPopover services are available
$scope.modelDataDynamic=[];
$scope.COUNT=0;
var MODEL_JSON = {
'model-1-a': 'a.json',
'model-1-b': 'b.json',
'model-1-c': 'c.json',
'model-1-d': 'd.json',
'model-1-e': 'e.json',
'model-1-f': 'f.json',
}
//load MODEL_JSON files
console.log('load MODEL_JSON files');
//==================================================
//==================================================
angular.element(document).ready(function () {
console.log("Register the LoadJson-Complete");
//==== LoadJSON COMPLETE
$scope.$root.$on('LoadJSON-complete', function (event, args) {
console.log("LoadJSON-complete event");
//will print to console the event name - LoadJSON-Complete
console.log("name=" + event.name)
// the data was the event returns
$scope.modelDataDynamic[$scope.COUNT].jsonData = args.data;
//print to the console to check the data
console.log(JSON.stringify($scope.modelDataDynamic[$scope.COUNT].jsonData))
// debugging inof
console.log("key=" +$scope.modelDataDynamic[$scope.COUNT].key+";value="
+ $scope.modelDataDynamic[$scope.COUNT].value + ";COUNT="+$scope.COUNT+
"length="+$scope.modelDataDynamic.length);
// this a double check we will convert it to string and parse it back to json
//this will ensure that data is correct and has the correct syntax
if( ++$scope.COUNT > $scope.modelDataDynamic.length-1)
{//finished
$scope.finished();
}
else
{$timeout($scope.GetJsonFromTwxRepository('/test/jsons/'
+ $scope.modelDataDynamic[$scope.COUNT].value),500,true)
}
});
})
//===================================================
//==================================================
$scope.GetJsonFromTwxRepository = function (path) {
console.log("$scope.GetJsonFromTwxRepository(path="+path+") ");
$timeout(function () {
// $rootScope.$broadcast('app.mdl.TestRepository.svc.LoadJSON',
twx.app.fn.triggerDataService('TestRepository','LoadJSON',
{"path": path});}
, 5,true);
console.log("after call of GetJsonFromTwxRepository")
};
//==================================================
//==================================================
$scope.$on('$ionicView.afterEnter', function () {
console.log("$ionicView.afterEnter was called ");
console.log('Calling now the service in a loop');
$scope.COUNT=0;
angular.forEach(MODEL_JSON, function (value, key) {
console.log("calling angular.forEach value="+value+ " key="+key);
let temp_obj= {}
temp_obj.key=key
temp_obj.value=value
$scope.modelDataDynamic.push(temp_obj) })
$timeout(()=>{
$scope.GetJsonFromTwxRepository('/test/jsons/' +$scope.modelDataDynamic[$scope.COUNT].value)
$scope.$applyAsync();
},100,true)
})
//=======================$scope.finished();=========
//==================================================
//$scope.$watch('COUNT', function (newValue, oldValue, scope) {
//if(scope.app.params.SVC_CALL_NUM <1)
$scope.finished=function(){
console.warn("completed the loop");
let a = $scope.modelDataDynamic
for (var i in a)
{ console.log("here Json for $scope.modelDataDynamic["+i+"]")
console.log("key="+ a[i].key + " value="+a[i].value)
console.log("==============================================")
console.log(JSON.stringify(a[i].jsonData));
console.log("==============================================")
}
$timeout( function() { console.warn($scope.modelDataDynamic);}, 1000)
}
So when tested I was working fine with the following print: