I am building a typescript interface to an API that I do not control. The API is xml based and expects properties in a particular order. These properties are not all required, but if they exist they must come in their proper order. Example:
database and query are required, the others are not but if they exist rowOffset
must come before rowCount
and rowCount
before formatValues
// Valid request
<database>my data</database>
<query>select * from some_table</query>
<formatValues>true</formatValues>
// Valid request
<database>my data</database>
<query>select * from some_table</query>
<rowOffset>1</rowOffset>
<formatValues>true</formatValues>
// Invalid request
<database>my data</database>
<query>select * from some_table</query>
<formatValues>true</formatValues>
<rowOffset>1</rowOffset> // formatValues must come after rowOffset if it exists
The typescript signature for this request looks like this
sqlQuery(database: string, query: string, options: object) : Promise
database and query are required and must be specified, the other options go to an object and we extend it with our required params and convert the whole thing to xml and send it on its way. The problem is that the options will be converted to xml attributes in order and so I need to enforce the order of the attributes, without enforcing the existence of these attributes.
I thought a map could do the trick, but I can't figure out how to make a custom type from a map. I could do an interface
interface OptionalParams {
rowOffset? : string,
rowCount? : string,
formatValues? :string,
}
but this won't enforce the order they exist in relative to each other. Is there any such type that can do this?
I found this question while searching for the same thing. I don't know if you're still having trouble with this, but I learned about Map
in ES6 thanks to this: https://www.jstips.co/en/javascript/map-to-the-rescue-adding-order-to-object-properties/
Full doc: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
Since this question has had some renewed interest, I will post the solution I ended up with. For every API method, I keep a map of the appropriate params. In my case this is made easier by the fact that every service requires the params in the same order relative to each other. That is, row offset will always come before row count for any API method that accepts them. The map ends up looking like this
this.paramMap = new Map([['addRecord', ['table', 'returnModifiedData',]],
['deleteRecord', ['table', 'keyValue',]],
['getColumnInfoList', ['database', 'table',]], ... );
This map is then used to reorder the parameters before the request is sent like so
// Add params to the request in the propper order
addParams(params: XmlmcParams, paramMap: Array<string>): void {
let orderedParams: XmlmcParams = {};
// ensure that all the params are in the proper order
paramMap.forEach((v) => {
if (params.hasOwnProperty(v)) {
orderedParams[v] = params[v];
}
});
// add ordered params to request
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.