Explanation of Ext.direct API - extjs

I'm trying to get a grip on Ext.direct. On the official page there is this description of the API:
The purpose of the API component of the Ext Direct stack is to output the method configurations for Ext Direct to create client-side stubs. By generating these proxy methods, we can seamlessly call server-side methods as if they were client-side methods without worrying about the interactions between the client and server-side.
I just don't quite get what it means by ...to output the method configurations for Ext Direct to create client-side stubs. Would someone care to explain what this means at a grassroots level?

This will make more sense if you look at the output from the api.php resource included in the following example.
Note that this is being loaded on the page as a <script/> tag, ie:
<script type="text/javascript" src="php/api.php"></script>
When you open the src link you'll see the following JavaScript being generated by server-side PHP (see block of javascript code below).
In other words, PHP is doing the bit where it ... output(s) the method configurations for Ext Direct to create client-side (ie JavaScript) stubs.
Now the next question you should be asking if you want to make sense of this is: Why bother generating client side JavaScript using server side PHP (or other language of choice)?.
Ext.ns("Ext.app");
Ext.app.REMOTING_API={
"url": "php\/router.php",
"type": "remoting",
"actions": {
"TestAction": [{
"name": "doEcho",
"len": 1
}, {
"name": "multiply",
"len": 1
}, {
"name": "getTree",
"len": 1
}, {
"name": "getGrid",
"len": 1
}, {
"name": "showDetails",
"params": [
"firstName",
"lastName",
"age"
]
}],
"Profile": [{
"name": "getBasicInfo",
"len": 2
}, {
"name": "getPhoneInfo",
"len": 1
}, {
"name": "getLocationInfo",
"len": 1
}, {
"name": "updateBasicInfo",
"len": 0,
"formHandler": true
}]
}
};
This seems to be mimicking the way a WSDL works in that it can provide a service description and list all the options available for quering. In other words: Ext.Direct API is taking a concept from SOAP and applying it to a Javascript setting.
The back-end contains the API so this is the easiest place to generate a service definition with all the method names and signatures. Once the Ext.Direct API method stubs are provided (in the back-end), the front-end Ext.Direct library will do the plumbing and turn these into actual functionality that can be queried and used in JavaScript. Much in the same way as SOAP proxy classes can be automatically generated (in PHP/C# or Java) using the WSDL.
Personally I think this is a bit too airy-fairy for my liking. Most APIs are pretty straight forward and trying to implement something akin to WSDL actually makes consumption a lot harder than it would be if you just talk to it directly.

Related

Getting shareable link to document in react app

I am currently making an app that generates Itineraries and I am able to convert the html to pdf using PDFjs using something like this:
var doc = new jsPDF();
doc.fromHTML(html);
doc.save("YourItinerary.pdf");
How should I proceed about making a shareable link to this pdf on client-side preferably using an API such as Google Drive?
Getting the shareable link would be to get the webViewLink which you can try by passing webViewLink as parameter in the 'fields' property in Files.get. This returns a link you can open in any browser. However, you also have to deal with permissions.
To make the webViewLink (your shareable link) work for anyone you can use in Permissions.create:
{
"role": "writer",
"type": "anyone",
}
To make the webViewLink available to certain users only you'll have a request body like:
{
"role": "writer",
"type": "user",
"emailAddress": "someuser#gmail.com"
}

Use parametrized values with Azure Logic App

I'm working with an Azure LogicApp where the workflow have fixed values. Our DevOps tool is VSTS (Visual Studio Team Services) and because we have multiple environments to handle, I have to do some refactoring (using parametrized values) so in VSTS we'll be able to provide environment-specific values.
Thanks to 2 websites I found on Internet I managed to understand that there are 3 kind of parameters :
To understand my problem, here's my action :
I want to have my string "/work/documents" in a parameter value. So in the "Code view" I managed to use a parameter instead of a hard-coded value :
"triggers": {
"When_a_file_is_added_or_modified": {
"type": "ApiConnection",
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['sftp_1']['connectionId']"
}
},
"method": "get",
"path": "/datasets/default/triggers/onupdatedfile",
"queries": {
"folderId": "#{parameters('pathToRootFolder')}"
}
},
"recurrence": {
"frequency": "Hour",
"interval": 1
}
}
}
And in my parameters.json :
"sftp_1_path_root_folder": {
"value": "/work/documents"
}
Here's the final result in Visual Studio:
Am I missing something ? Why isn't the value displayed in the Designer ? Thank you for your help in advance !
When you are using Logic Apps parameters inside your Logic App definition, they are not resolved at design-time, but at run-time. Thus, you are not supposed to see them in the designer. If you run the workflow, you should be able to see the actual value at run-time.
If you want to resolve those parameters at deployment-time, then you would need to write directly from the ARM template using ARM parameters into the workflow definition. This is possible, but in some cases, it can become a bit more complex. That's why I prefer to make use of Logic Apps parameters as described here.

Is including additional information in the output object a good idea?

I'm experimenting with a Conversation where I would like to modify the output in a couple of different ways:
different output for speech or text
different output depending on the tone of the conversation
It looks like I can add extra output details which make it through to the client ok. For example, adding speech alongside text...
{
"output": {
"speech": {
"Hi. Please see my website for details."
},
"link": "http://www.example.com",
"text": {
"Hi. Please see http://www.example.com for details."
}
}
}
For the tone, I wondered about making up a custom selection policy, unfortunately it seems to treat it the same as a random selection policy. For example...
{
"output": {
"text": {
"values": [
"Hello. Please see http://www.example.com for more details.",
"Hi. Please see http://www.example.com for details."
]
},
"append": false,
"selection_policy": "tone"
}
}
I could just add a separate tone-sensitive object to output though so that's not a big problem.
Would there be any issues adding things to output in this way?
You can definitely use the output field to specify custom variables you want your client app to see with the benefit that these variables will not persist across multiple dialog rounds (which they would if you would add them to the context field).
Now currently there is no "easy" way how to define your custom selection policy (apart from the random and sequential supported by the runtime right now) - but you could still return an array of possible answers to the client app with some attribute telling the client app which selection policy to use and you would implement this policy in the client app.

String concatenation issue with Azure Logic Apps

I'm creating an ARM template that deploys an Web App (an Mvc Api) and a Logic App.
I'm attempting to define an HTTP Action within the Logic App such that it dynamically concatenates the base Uri of the Api as well as a property of the current item using splitOn and #triggerBody(). The base Uri itself is concatenated from a set of parameters in the ARM template into a variable variables('hockeyAppAPISettings').Uri.
Here's the relevant snipped of the action definition:
"actionName": {
"conditions": [ ],
"inputs": {
"authentication": {
"audience": "[variables('apiSettings').Authentication.Audience]",
"clientId": "[variables('apiSettings').Authentication.ClientId]",
"secret": "[variables('apiSettings').Authentication.Secret]",
"tenant": "[variables('apiSettings').Authentication.Tenant]",
"type": "ActiveDirectoryOAuth"
},
"method": "patch",
"uri": "[concat(variables('apiSettings').Uri, '/#{triggerBody()['Id']}/ScanningInProgress')]"
//"uri": "[concat(variables('apiSettings').Uri, '//#{triggerBody()[/'Id/']}//ScanningInProgress')]"
//"uri": "[concat(variables('apiSettings').Uri, '//##{triggerBody()[/'Id/']}//ScanningInProgress')]"
},
"type": "Http"
},
The "uri" section is what i'm struggling with. I've sprinkled various escape characters (\ and #) in differing patterns through out this.
I either can't get the deployment to succeed w/deployment errors like:
Unable to parse template language expression
'concat(variables('apiSettings').Uri,
'//#{triggerBody()[/'Id/']}//ScanningInProgress')': expected token
'RightParenthesis' and actual 'Identifier'. Please see
http://aka.ms/arm-template-expressions for usage details..'.
Or if I get the deployment working and then look at the code in the portal after deployment, the string concatenation doesn't seem to work properly. The variable doesn't get converted to its value.
I have validated that if I edit the Uri directly (via the portal HTML editor) using this: "uri" : "https://edited.azurewebsites.net/api/Packages/#{triggerBody()['Id']}/ScanningInProgress" the Logic App will make a patch call for each item that comes from the HTTP trigger.
What am I doing wrong?
You need to escape the inner single quotes, i.e. try
"uri": "[concat(variables('apiSettings').Uri, '/#{triggerBody()[''Id'']}/ScanningInProgress')]"
Alternatively you can use the dot notation to reference the property, i.e.
"uri": "[concat(variables('apiSettings').Uri, '/#{triggerBody().Id}/ScanningInProgress')]"
For me changing this
"uri": "[concat(parameters('APIMUrl_param'), '/sales-management/differential-reference-codes/v1/?instance=', parameters('APIDRCInstance_param'), '&filter=differentialReferenceCode%20eq%27', variables('varDRC'), '%27')]",
to this has worked
"uri": "#concat(parameters('APIMUrl_param'), '/sales-management/differential-reference-codes/v1/?instance=', parameters('APIDRCInstance_param'), '&filter=differentialReferenceCode%20eq%27', variables('varDRC'), '%27')",

How do I perform specific parentless requests using Restangular in a neat way?

Say I have an API endpoint at /users and another one at /cars. Naturally, a GET request to either of them will get all users or cars available. Now, a GET /users/74/cars should return all cars belonging to user 74.
But my app has many models related to cars, not just users, so more endpoints exist like /shops/34/cars and /mechanics/12/cars. For simplicity, I want all PUT/PATCH requests to be made to the main /cars endpoint.
At the moment of performing the save, Restangular will by default do a PUT request to the endpoint through which the item was loaded. But that endpoint do not exist.
It also provides a nice Restangular.setParentless(['cars']) method that will discard the first part of the url. However, I don't want to do this globally, but specifically for a particular element.
The neatest would actually do it globally, but restrict it for a specific method, like: Restangular.setParentless(['cars'], ['PUT']).
Anything like that around? Or am I overcomplicating it?
So far I tried stuff I don't like:
delete car.parentResource;
I would recommend using self reference links. A self reference link is a link which stores the route which should be used for GET/PUT/DELETE etc. on the item, rather than the URL from which it was pulled.
Example, update the mileage on one of user id 74's cars:
First, configure Restangular to look for a self link property called 'self' on each object.
RestangularProvider.setRestangularFields({
selfLink: 'self'
});
Next, make your call to get the cars. I'll assume that you have already modified your API to return a property called 'self' on each object that has the URL to it's proper API endpoint.
GET /users/74/cars
[
{
"id": 12,
"model": "Camaro",
"make": "Chevrolet",
"year": 1969,
"color": "red",
"odometer": 67294,
"license": "ABC12345",
"self": "/cars/12"
},
{
"id": 14,
"model": "Gallardo",
"make": "Lamborghini",
"year": 2015,
"color": "black",
"odometer": 521,
"license": "XYZ34567",
"self": "/cars/14"
}
]
We want to add some miles to one of them, and then save it. The entire Restangular code would look like:
Restangular.one('users', 74).all('cars').getList().then(function(cars){
cars[1].odometer = 613;
cars[1].put();
});
The PUT will go to /cars/14 instead of /users/74/cars/14. This is very useful for applications like yours that relate models as a graph rather than a strict hierarchical tree.

Resources