Parsing JSON with Brightscript - json

I'm trying to parse JSON, based on the example here: http://blog.roku.com/developer/2012/07/16/json-support-comes-to-roku/
jsonAsString = ReadAsciiFile("pkg:/json/sample1.json")
m.json = ParseJSON(jsonAsString)
ShowPosterScreen(m.json.Videos, true)
I get this message in the debugger console:
Current Function:
057: Function LoadJSONFile() as void
058: jsonAsString = ReadAsciiFile("pkg:/json/sample1.json")
059: m.json = ParseJSON(jsonAsString)
060: ShowPosterScreen(m.json.Videos, true)
061: End Function
'Dot' Operator attempted with invalid BrightScript Component or interface reference. (runtime error &hec) in ...AALAE4Bk/pkg:/source/main.brs(60)
060: ShowPosterScreen(m.json.Videos, true)
Backtrace:
Function loadjsonfile() As
file/line: /tmp/plugin/D...AALAE4Bk/pkg:/source/main.brs(60)
Function handlebuttonpress(id As Integer) As
file/line: /tmp/plugin/D...AALAE4Bk/pkg:/source/main.brs(51)
Function main() As
file/line: /tmp/plugin/D...AALAE4Bk/pkg:/source/main.brs(26)
Local Variables:
global &h0020 rotINTERFACE:ifGlobal
m &h0010 bsc:roAssociativeArray, refcnt=4
jsonasstring &h8010 bsc:roString (2.1 was String), refcnt=1
BrightScript Debugger>
UPDATE: If I include a Makefile and zip the contents and load through development browser...it works. Not working when exporting through Eclipse.

That sounds like a bug in the Eclipse Brightscript plugin of some kind, most likely, in some way it is not loading the file containing your ShowPosterScreen function.
Please check the Roku Developer forum, at the very top is the section for discussion of the Eclipse Plugin. Here is a direct link.

Related

How to convert Pulumi Output<t> to string?

I am dealing with creating AWS API Gateway. I am trying to create CloudWatch Log group and name it API-Gateway-Execution-Logs_${restApiId}/${stageName}. I have no problem in Rest API creation.
My issue is in converting restApi.id which is of type pulumi.Outout to string.
I have tried these 2 versions which are proposed in their PR#2496
const restApiId = apiGatewayToSqsQueueRestApi.id.apply((v) => `${v}`);
const restApiId = pulumi.interpolate `${apiGatewayToSqsQueueRestApi.id}`
here is the code where it is used
const cloudWatchLogGroup = new aws.cloudwatch.LogGroup(
`API-Gateway-Execution-Logs_${restApiId}/${stageName}`,
{},
);
stageName is just a string.
I have also tried to apply again like
const restApiIdStrign = restApiId.apply((v) => v);
I always got this error from pulumi up
aws:cloudwatch:LogGroup API-Gateway-Execution-Logs_Calling [toString] on an [Output<T>] is not supported.
Please help me convert Output to string
#Cameron answered the naming question, I want to answer your question in the title.
It's not possible to convert an Output<string> to string, or any Output<T> to T.
Output<T> is a container for a future value T which may not be resolved even after the program execution is over. Maybe, your restApiId is generated by AWS at deployment time, so if you run your program in preview, there's no value for restApiId.
Output<T> is like a Promise<T> which will be eventually resolved, potentially after some resources are created in the cloud.
Therefore, the only operations with Output<T> are:
Convert it to another Output<U> with apply(f), where f: T -> U
Assign it to an Input<T> to pass it to another resource constructor
Export it from the stack
Any value manipulation has to happen within an apply call.
So long as the Output is resolvable while the Pulumi script is still running, you can use an approach like the below:
import {Output} from "#pulumi/pulumi";
import * as fs from "fs";
// create a GCP registry
const registry = new gcp.container.Registry("my-registry");
const registryUrl = registry.id.apply(_=>gcp.container.getRegistryRepository().then(reg=>reg.repositoryUrl));
// create a GCP storage bucket
const bucket = new gcp.storage.Bucket("my-bucket");
const bucketURL = bucket.url;
function GetValue<T>(output: Output<T>) {
return new Promise<T>((resolve, reject)=>{
output.apply(value=>{
resolve(value);
});
});
}
(async()=>{
fs.writeFileSync("./PulumiOutput_Public.json", JSON.stringify({
registryURL: await GetValue(registryUrl),
bucketURL: await GetValue(bucketURL),
}, null, "\t"));
})();
To clarify, this approach only works when you're doing an actual deployment (ie. pulumi up), not merely a preview. (as explained here)
That's good enough for my use-case though, as I just want a way to store the registry-url and such after each deployment, for other scripts in my project to know where to find the latest version.
Short Answer
You can specify the physical name of your LogGroup by specifying the name input and you can construct this from the API Gateway id output using pulumi.interpolate. You must use a static string as the first argument to your resource. I would recommend using the same name you're providing to your API Gateway resource as the name for your Log Group. Here's an example:
const apiGatewayToSqsQueueRestApi = new aws.apigateway.RestApi("API-Gateway-Execution");
const cloudWatchLogGroup = new aws.cloudwatch.LogGroup(
"API-Gateway-Execution", // this is the logical name and must be a static string
{
name: pulumi.interpolate`API-Gateway-Execution-Logs_${apiGatewayToSqsQueueRestApi.id}/${stageName}` // this the physical name and can be constructed from other resource outputs
},
);
Longer Answer
The first argument to every resource type in Pulumi is the logical name and is used for Pulumi to track the resource internally from one deployment to the next. By default, Pulumi auto-names the physical resources from this logical name. You can override this behavior by specifying your own physical name, typically via a name input to the resource. More information on resource names and auto-naming is here.
The specific issue here is that logical names cannot be constructed from other resource outputs. They must be static strings. Resource inputs (such as name) can be constructed from other resource outputs.
Encountered a similar issue recently. Adding this for anyone that comes looking.
For pulumi python, some policies requires the input to be stringified json. Say you're writing an sqs queue and a dlq for it, you may initially write something like this:
import pulumi_aws
dlq = aws.sqs.Queue()
queue = pulumi_aws.sqs.Queue(
redrive_policy=json.dumps({
"deadLetterTargetArn": dlq.arn,
"maxReceiveCount": "3"
})
)
The issue we see here is that the json lib errors out stating type Output cannot be parsed. When you print() dlq.arn, you'd see a memory address for it like <pulumi.output.Output object at 0x10e074b80>
In order to work around this, we have to leverage the Outputs lib and write a callback function
import pulumi_aws
def render_redrive_policy(arn):
return json.dumps({
"deadLetterTargetArn": arn,
"maxReceiveCount": "3"
})
dlq = pulumi_aws.sqs.Queue()
queue = pulumi_aws.sqs.Queue(
redrive_policy=Output.all(arn=dlq.arn).apply(
lambda args: render_redrive_policy(args["arn"])
)
)

Read local JSON files when dynamically creating functional tests in Intern

I am creating functional tests dynamically using Intern v4 and dojo 1.7. To accomplish this I am assigning registerSuite to a variable and attaching each test to the Tests property in registerSuite:
var registerSuite = intern.getInterface('object').registerSuite;
var assert = intern.getPlugin('chai').assert;
// ...........a bunch more code .........
registerSuite.tests['test_name'] = function() {
// READ JSON FILE HERE
var JSON = 'filename.json';
// ....... a bunch more code ........
}
That part is working great. The challenge I am having is that I need to read information from a different JSON file for each test I am dynamically creating. I cannot seem to find a way to read a JSON file while the dojo javascript is running (I want to call it in the registerSuite.tests function where it says // READ JSON FILE HERE). I have tried dojo's xhr.get, node's fs, intern's this.remote.get, nothing seems to work.
I can get a static JSON file with define(['dojo/text!./generated_tests.json']) but this does not help me because there are an unknown number of JSON files with unknown filenames, so I don't have the information I would need to call them in the declare block.
Please let me know if my description is unclear. Any help would be greatly appreciated!
Since you're creating functional tests, they'll always run in Node, so you have access to the Node environment. That means you could do something like:
var registerSuite = intern.getPlugin('interface.object').registerSuite;
var assert = intern.getPlugin('chai').assert;
var tests = {};
tests['test_name'] = function () {
var JSON = require('filename.json');
// or require.nodeRequire('filename.json')
// or JSON.parse(require('fs').readFileSync('filename.json', {
// encoding: 'utf8'
// }))
}
registerSuite('my suite', tests);
Another thing to keep in mind is assigning values to registerSuite.tests won't (or shouldn't) actually do anything. You'll need to call registerSuite, passing it your suite name and tests object, to actually register tests.

Examining the Windows Store apps AppxManifest at Runtime

I try to load the AppxManifest at Runtime to read out the Version of the app. I fond this article:
http://tonychampion.net/blog/index.php/2013/01/examining-the-windows-store-apps-appxmanifest-at-runtime/#comments
I tried the line from the post:
var doc = XDocument.Load("AppxManifest.xml", LoadOptions.None);
But this will throw me the following exception:
{System.Xml.XmlException: An internal error has occurred.
at System.Xml.XmlXapResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
at System.Xml.XmlTextReaderImpl.FinishInitUriString()
at System.Xml.XmlTextReaderImpl..ctor(String uriStr, XmlReaderSettings settings, XmlParserContext context, XmlResolver uriResolver)
at System.Xml.XmlReaderSettings.CreateReader(String inputUri, XmlParserContext inputContext)
at System.Xml.XmlReader.Create(String inputUri, XmlReaderSettings settings, XmlParserContext inputContext)
at System.Xml.Linq.XDocument.Load(String uri, LoadOptions options)
at MyMedi.Src.Utilities.GetVersion()
at MyMedi.WindowsPhone.Test.Src.UtilitiesTest.Utilities_GetVersionTest()}
Can anyone tell me what I'm doing wrong?
Thanks
NPadrutt
I'm not sure why you'd want to, but you could try loading the document with the ms-appx:// uri schema in the file reference.
There's a much easier way to achieve your goal, though.
Package package = Package.Current;
PackageId packageId = package.Id;
PackageVersion version = packageId.Version;
var versionString = string.Format(
CultureInfo.InvariantCulture,
"{0}.{1}.{2}.{3}",
version.Major,
version.Minor,
version.Build,
version.Revision);

Am I using the wrong standard for JSON response?

I am new to Angular and I am trying to build a simple todo application using it. I have designed a module called TodoServices in which I am creating a User service using the factory method. The code looks something like:
angular.module('TodoServices', ["ngResource"])
.factory('User', function($resource){
return $resource('http://todoapi.rohanchhabra.in/users/:id');
});
The code in my app.js looks like:
var angularApp = angular.module('angularApp', ['TodoServices']);
angularApp.controller('UsersController', function(User){
this.users = {};
this.users = User.query();
});
When I run my application, I get this error: Error link
I think this is because my web service is returning an object which not only has the data but also has a few other things such as a status and messages. Now Is it a wrong way of doing it? Should I just return the array from the back end? What is the actual problem here and how to solve this?
As your error link says:
By default, all resource actions expect objects, except query which expects arrays.
You should use an other function like User.Get() when you're not expecting an array but just a single object.

Sharing Functions between Chrome Extensions

I am making an extension (A) for Chrome that communicates with another extension (B). I want A to provide the B a function, but it won't send. I can send strings just fine.
A has the following code. rect is the function in this code.
chrome.extension.onRequestExternal.addListener(
function(request, sender, sendResponse) {
obj = {}
obj.permisions = "all"
obj.rect = Rect
alert(obj.permisions+","+obj.rect)
sendResponse(obj);
});
...this code works just fine. The alert shows a box that says "all", then prints out the function.
B has the following code.
chrome.extension.sendRequest(ext[i].id, {}, function(lib) {
alert(lib.permisions+","+lib.rect)
});
The alert on this one shows "all,undefined". Can functions not be passed between extensions?
While you can certainly communicate between extensions, you can only pass valid JSON. Unfortunately, valid JSON only includes simple data types(String, Number, Boolean, Array, Object* or Null).
One way to do it would be to pass the function as a String and use eval on the receiving end. Could be unsafe, but is doable.
* While a function is technically an Object, in this context Object refers to name:value pairs of the aforementioned simple data types.