Canvas PowerApp Form unable to get fields from Custom Connector returning tabular data from REST API - forms

I created a Custom Connector our of my REST API that returns tabular data. I used it as a datasource in a canvas powerapp, which store the records from the custom connector into a collection. This collection is used as datasource by a Gallery which successfully displays the items and attributes of each item. However, when I try to create an Edit Form that uses the collection as datasource it cannot access the fields. It does not work using directly the custom connector as data source either.
In this answer from #aorphan I read that you can use custom connectors in forms as long as they return tables instead of actions. And as far as I can see, the content of the collection is tabular data:
Even the columns of the collection can be accessed as attributes of the item displayed by the Gallery:
However, even after setting the collection as datasource of a new Edit Form, it is unable to add any fields from the datasource:
Just in case my data needs some richer definition to be correctly interpreted by the Form, the JSON returned by my API looks like this:
{
"quotes": [
{
"quote_pk": 347,
"shipment_name": "test add leg",
"organization_ff_name": "LIFE",
"quote_id": "1234",
"effective_until": "2020-05-10",
"eta": "2020-05-14T12:00:00Z",
"price": 100.0,
"quote_status": 2
},
{
"quote_pk": 345,
"shipment_name": "test modal review",
"organization_ff_name": "LIFE",
"quote_id": "123",
"effective_until": "2020-05-11",
"eta": "2020-05-22T12:00:00Z",
"price": 1749.94,
"quote_status": 6
}
]
}
And the definition of my Custom Connector goes like this:
swagger: '2.0'
info: {title: some title, description: some description, version: '1.0'}
host: server.domain.com
basePath: /organizations/endpoint/
schemes: [https]
consumes: []
produces: []
paths:
/organizations/endpoint/shipment_quotes/: {}
/shipment_quotes/:
get:
responses:
'200':
description: default
schema:
type: object
properties:
quotes:
type: array
items:
type: object
properties:
quote_pk: {type: integer, format: int32, description: quote_pk}
shipment_name: {type: string, description: shipment_name}
organization_ff_name: {type: string, description: organization_ff_name}
quote_id: {type: string, description: quote_id}
effective_until: {type: string, description: effective_until}
eta: {type: string, description: eta}
price: {type: number, format: float, description: price}
quote_status: {type: integer, format: int32, description: quote_status}
description: quotes
summary: peration summary
description: operation description
operationId: operationId
parameters:
- {name: Content-Type, in: header, required: false, type: string}
- {name: Accept, in: header, required: false, type: string}
definitions: {}
parameters: {}
responses: {}
securityDefinitions: {}
security: []
tags: []
Please help me to get the datasource right so the form be able to add its fields, or at least let me know in case this is not possible for some reason so I can move on.

Formally, Collections cannot be used as a DataSource for Form controls in PowerApps. You're efforts are admirable and it looks like you've tried just about everything, so I'll pass my little secret.
Its probably not officially supported so use at your own risk.
Create a Collection of the response from your Custom Connector (which you've done)
Add a Gallery control and set its Items property to the Collection (which you've already done)
Add an Edit Form control and set its DataSource property to the Collection (which you've already done)
Click the three little dots and Add Custom Card
Add a TextBox control to the Custom Card.
Set the TextBox Default property to gallery.Selected.X where "X" is the value you want to edit in the form.
Repeat steps 4-7 for each form field you wish to capture.
Create a "Submit" button in the Form which Patches/UpdateIf's the Collection then calls your POST (or PUT) method from the Custom Connector to patch the edits back to your DataSource.
8a. I only see a GET request in your swagger file. You'll (obviously) need a POST/PUT to get the data from the Collection back up to your DataSource.
8b. This little "wrapper" is likely what PowerApps handles for you when you use an "approved" DataSource for a Form control.
Note: Your Form will show "No data source" in the PowerApps studio, but your user won't see it.
Here it is in action:
Help much?

Related

OpenAPI 3: How to require one or more properties in PATCH requestBody?

I have a User resource:
I want to define a PATCH /users/{uid} so that the client can update image, bio or both.
An example valid request body would be:
{
"image": "filename.jpg",
"bio": "My biography"
}
If the image property is sent alone the existing bio property will remain the same on the server and only the image will be updated. If both are sent (as above) both will change.
In short:
an empty request body {} is disallowed.
{"image": "new.jpg"}, {"bio": "new bio" or {"image": "new.jpg", "bio": "new bio" is allowed.
This is what I have so far. I'm using the anyOf object with two separate type: objects within. I've tried this with Swagger hub using the virtserver, but the virtual server always seems to return 200 OK and passes back the example data regardless of whatever is passed, so I have no way to know.
Does my definition do what I intended? If not, what the best practice?
openapi: 3.0.0
...
patch:
summary: update a user
parameters:
- in: path
name: uid
description: user id
schema:
type: string
required: true
requestBody:
description: Update a user's profile
content:
application/json:
schema:
type: object
anyOf:
- type: object
properties:
image:
type: string
- type: object
properties:
bio:
type: string
additionalProperties: false
required: true
responses:
'200':
description: Successfully updated
content:
application/json:
schema:
$ref: '#/components/schemas/User'
You can use minProperties: 1:
requestBody:
description: Update a user's profile
content:
application/json:
schema:
type: object
properties:
image:
type: string
bio:
type: string
minProperties: 1 # <-----------
additionalProperties: false
or anyOf + required:
type: object
properties:
image:
type: string
bio:
type: string
anyOf: # <-----------
- required: [image]
- required: [bio]
additionalProperties: false
Your original example defines an empty object {} because:
Without required or minProperties defined, all properties are optional.
More importantly, additionalProperties: false only knows about the properties defined directly alongside it and has no visibility into subschemas. So, in this example it disallows ALL properties.
As for:
I've tried this with SwaggerHub using the VirtServer, but the virtual server always seems to return 200 OK and passes back the example data regardless of whatever is passed.
This is because SwaggerHub mocks do not validate inputs and always return a static response based on the response schema.
From SwaggerHub documentation:
Note that the mock does not support business logic, that is, it cannot send specific responses based on the input.
...
The mock generates static responses for each API operation based on its responses and the response media types defined in the spec.
If an operation has multiple response codes, the mock returns the response with the lowest status code. For example, if an operation has responses 201, 202 and 400, the mock returns the 201 response.

How do I express JSON-API sparse fieldsets with OpenAPI-3.0

I'm implementing an OpenAPI-3.0 spec for my API, and I plan on using sparse fieldsets as a parameter for GETs. The examples for parameters using style=deepObject are a little sparse, so I'm not sure if I've got this exactly right.
- in: query
name: fields
style: deepObject
schema:
type: object
additionalProperties:
type: string
Can I combine both the deepObject and additionalProperties options?
I want to support flexible query parameter inputs like this:
GET /articles?include=author&fields[articles]=title,body&fields[people]=name
but I don't want to have to spell out every single option for each resource and field.
Your definition is correct. You might also need to add allowReserved: true so that the comma in =title,body is not percent-encoded, and you can add a parameter example value for documentation purposes:
- in: query
name: fields
style: deepObject
allowReserved: true
schema:
type: object
additionalProperties:
type: string
example:
articles: title,body
people: name
When using "try it out" in Swagger UI, enter the parameter value in the JSON format like so:
{
"articles": "title,body",
"people": "name"
}
Swagger UI will serialize the parameter as
?fields[articles]=title,body&fields[people]=name

Database design - saving the entire object to a user or just the id of an object?

database noob here using MongoDB, in my program, I have users, and the core of my program are these roadmaps that I display. So, each user can create roadmaps, save others roadmaps, blah blah... Each user has a field named savedRoadmaps and createdRoadmaps which should store the roadmaps. My question is, should I just store the roadmap _ids in the savedRoadmap and createdRoadmaps field or the entire roadmap?
I am asking this because it feels like saving just the _id of the roadmaps can save storage, but it might not come in handy when I have to fetch the data of the user first, then fetch the roadmap using the roadmap ID in the user's savedRoadmap/createdRoadmap field, versus just fetching the user and the savedRoadmap field will already have the roadmap in there.
And btw, is there any sweet and brief database design read out there, please direct me to some if you know any!
For a user, I want it to have a name, email, password, description ofcourse, and also savedRoadmaps and createdRoadmaps. A user can create unlimited roadmaps and also save as much as he or she wants. For a roadmap, I want it to have a name, category, time_completion, author, date, and a roadmap object which will contain the actual json string that I will use d3 to display. Here's my User and Roadmap Schema right now:
const RoadmapSchema = new Schema({
author: {
type: String,
require: false
},
name: {
type: String,
require: true
},
category: {
type: String,
require: true
},
time_completion: {
type: Number,
require: true
},
date: {
type: Date,
default: Date.now
},
roadmap: {
type: "object",
require: true
}
});
and User Schema:
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
savedRoadmap: {
type: "object",
default: []
},
createdRoadmap: {
type: "object",
default: []
}
});
My question is, inside of the savedRoadmap and createdRoadmap fields of the User schema, should I include just the _id of a roadmap, or should I include the entire json string which represents the roadmap?
There are 3 different data-modeling techniques you can use to design your roadmaps system based on the cardinality of the relationship between users and roadmaps.
In general you need to de-normalize your data model based on the queries that are expected from your application:
One to Few: Embed the N side if the cardinality is one-to-few and there is no need to access the embedded object outside the context of the parent object
One to Many: Use an array of references to the N-side objects if the cardinality is one-to-many or if the N-side objects should stand alone for any reasons
One-to-Squillions: Use a reference to the One-side in the N-side objects if the cardinality is one-to-squillions
And btw, is there any sweet and brief database design read out there,
please direct me to some if you know any!
Rules of Thumb for MongoDB Schema Design: Part 1

How to retrieve field names in jaydata

I have a simple database in Jaydata:
$data.Entity.extend("Person", {
Name: { type: String, required: true},
LastName: {type: String, required: true},
DepartmentId: {type: int}
});
$data.EntityContext.extend("PersonDatabase", {
People : { type : $data.EntitySet, elementType : Person}
});
var Database1= new PersonDatabase("MyDatabase");
But suppose I don't know the fields of the database I have. Assume I only know the variable Database1 so I need to make a loop which returns column names(fields of "Person"). How can I make that so I can make a dynamic table which can show whatever simple database(#x columns, #y rows) data I will have?
If you have a type in hand for example the Person class, call type.getFieldNames() for and array of public mapped field names (technical fields are not visible). To access each and every field with full metadata consult type.memberDefinitions or type.memberDefinitions.toArray()
The http://admin.jaystack.net site is build with fully generic table routines powered by knockout: check out admin.jaystack.net for an example (you need to register for a free account to access the admin site)

Mongoose validating embedded

I created the following schema (coffeescript):
user_schema = new app.db.schema(
username: String
email: String
password: String
account:
plan:
type: String
default: "Free"
enum: ["Free", "Bronze", "Silver", "Gold"]
comments: [
title: String
message: String
date_added: Date
]
)
I could have probably created 2 more schemas here (account and comment) but I know each user has one account associated and each account has maximum 100 comments so I like the idea of having it all inside a single document. It's not making sense I know (user/account/comments) but I'm just familiarizing myself to noSql and rich documents so it's just a test.
My question is about saving a new comment for a given account and validating them. I can validate a user email by doing this (which works btw):
user_schema.path("email").validate((value, respond)->
respond v.check(value).isEmail()
, "Invalid email address")
...but how would I validate a comment? How do I save a new comment under a given user.account.comments array? Comments are not required by default but if a new comment is added I want to validate that the title and message is required let's say.
Is this type of nesting normal or I have to create separate models and reference them? I read a lot about embedding vs linking and I feel like this would make for an embed?
You put the validation attributes right in the schema definition of the embedded object:
comments: [
title:
type: String
required: true
message:
type: String
required: true
date_added: Date
]