I'm developing a PowerBI data connector using the M language. I need to retrieve data from APIs in smaller portions and then combine them to present as a table using ToNavigation
. I'm currently encountering issues when trying to transform the data structure into a format that can be accepted as a table.
[DataSource.Kind="SchoolBI", Publish="SchoolBI.Publish"]
shared *** .Contents = () =>
let
key = Extension.CurrentCredential()[Key],
baseUrl = "https://api-stage.***.com/v3/data/data/", // Base URL
metricsUrl = baseUrl & "getavailablemetrics?data_report=powerbi&apiKey=" & key, // Metrics URL
dimensionsUrl = baseUrl & "getavailabledimensions?data_report=powerbi&apiKey=" & key, // Dimensions URL
dataSetUrl = baseUrl & "datasetmapping?data_report=powerbi&apiKey=" & key, // Data Source Mapping URL
dataSetMapper = Json.Document(Web.Contents(dataSetUrl)), // Json contains data from dataset endpoint
reverseDataSetMapper = Record.FromList(Record.FieldNames(dataSetMapper),Record.FieldValues(dataSetMapper)), // Swaping key value pair for dataset mapping
allMetrics = Json.Document(Web.Contents(metricsUrl)), // Contains all metrics for authorize data sets
allDimensions = Json.Document(Web.Contents(dimensionsUrl)), // Contains all dimensions for authorize data sets
allDataSets = Record.FieldNames(allDimensions),
allParameters = Record.Combine(List.Transform(allDataSets,each Record.AddField(\[\], Record.Field(dataSetMapper,Text.From(_)), Record.Combine({Record.Field(allMetrics,_),Record.Field(allDimensions,\_)})))) , // Combining all metrics and dimensions
friendlyNames = Record.FromList(
List.Transform(Record.FieldNames(allParameters), each
let
currentDataSource = _,
currentDataSourceDimensionAndMetrics = Record.Field(allParameters,_),
temp = Record.FieldNames(currentDataSourceDimensionAndMetrics),
getRecord = List.Transform(temp,each
let
currentMetricsOrDimensionKey = _,
currentDimensionOrMetrics = Record.Field(currentDataSourceDimensionAndMetrics,currentMetricsOrDimensionKey),
currentFriendlyName = {currentMetricsOrDimensionKey, Record.Field(currentDimensionOrMetrics,"friendly_name")}
in
currentFriendlyName
)
in
getRecord
),
Record.FieldNames(allParameters)
),
allFetchingUrl = List.Transform(allDataSets,each Record.AddField([],Record.Field(dataSetMapper,Text.From(_)),List.Combine({Record.FieldNames(Record.Field(allMetrics,Text.From(_))),Record.FieldNames(Record.Field(allDimensions,Text.From(_)))}))),
allDataSetUrls = List.Transform(allFetchingUrl,each Record.AddField([],Record.FieldNames(_){0},baseUrl & Record.FieldNames(_){0} & "?data=" & Text.Combine( Record.Field(_,Record.FieldNames(_){0}) ,",") & "&include_null=True&offset=0&limit=500&data_report=powerbi&apiKey=" & key)),
allPresignedUrls = List.Transform(allDataSetUrls,each
let
LoopFunction = (offset,limit,remainingCount) =>
if remainingCount >= 500 then
let
currentDataSource = _,
data = Record.Field(Json.Document(Web.Contents(Record.Field(currentDataSource,Record.FieldNames(_){0}))),"data")
in
data & @LoopFunction(offset+500,limit+500,remainingCount - 500)
else
{}
in
LoopFunction(0,500, 22510)
),
objects = #table(
{"Name", "Key", "Data",
"ItemKind", "ItemName", "IsLeaf"},latestOutput),
NavTable = Table.ToNavigationTable(objects, {"Key"}, "Name", "Data", "ItemKind", "ItemName", "IsLeaf")
in
NavTable;
SchoolBI = [
Authentication = [
Key = []
],
Label = Extension.LoadString("DataSourceLabel")
];
Table.ToNavigationTable = (
table as table,
keyColumns as list,
nameColumn as text,
dataColumn as text,
itemKindColumn as text,
itemNameColumn as text,
isLeafColumn as text
) as table =>
let
tableType = Value.Type(table),
newTableType = Type.AddTableKey(tableType, keyColumns, true) meta
[
NavigationTable.NameColumn = nameColumn,
NavigationTable.DataColumn = dataColumn,
NavigationTable.ItemKindColumn = itemKindColumn,
Preview.DelayColumn = itemNameColumn,
NavigationTable.IsLeafColumn = isLeafColumn
],
navigationTable = Value.ReplaceType(table, newTableType)
in
navigationTable;