Closed ArtashMardoyanS closed 8 months ago
@ArtashMardoyanS the error happens because count gets added to a request twice. Once with nextPageLink
and another with request.count
. A workaround for now, until I decide what to do with this:
const request = {
collection: 'contacts',
select: ['contactid'],
maxPageSize: 10,
count: true
};
const firstPage = await this.dynamicsWebApi.retrieveMultiple(request);
console.log(firstPage.value[0]);
const nextPageLink = firstPage['@odata.nextLink'];
console.log(nextPageLink);
//removing 'select' and 'count' from a request because they get duplicated in the result url
const nextPagesRequest = {
collection: request.collection,
maxPageSize: request.maxPageSize,
}
const secondPage = await this.dynamicsWebApi.retrieveMultiple(nextPagesRequest , nextPageLink);
P.S. I was getting a different error when trying to execute your request though:
'Query option '$count' was specified more than once, but it must be specified at most once.'
@AleksandrRogov thank you for your quick response.
Describe the bug We changed our code and tried to get the next page like your solution but we again received an error.
Actual result
The URI 'https://devsi.api.crm.dynamics.com/devsi.api.crm.dynamics.com/api/data/v9.2/contacts?$select=contactid&$count=true&$skiptoken=
Code Snippet
async retrieveContacts() {
try {
this.loggerService.trace(`[${this.constructor.name}.retrieveContacts]`);
const request = {
collection: 'contacts',
select: ['contactid'],
maxPageSize: 10,
count: true
};
const firstPage = await this.dynamicsWebApi.retrieveMultiple(request);
console.log(firstPage.value[0]);
const nextPageLink = firstPage['@odata.nextLink'];
console.log(nextPageLink);
//removing 'select' and 'count' from a request because they get duplicated in the result url
const nextPagesRequest = {
maxPageSize: request.maxPageSize,
collection: request.collection
};
const secondPage = await this.dynamicsWebApi.retrieveMultiple(nextPagesRequest, nextPageLink);
console.log(secondPage.value[0]);
return firstPage;
} catch (ex) {
this.loggerService.error(`[${this.constructor.name}.retrieveContacts]`, ex);
throw new InternalServerErrorException(ex);
}
}
@ArtashMardoyanS what's your DynamicsWebApi config? specifically server url in there? I see that for some reason your serverUrl gets duplicated. At least that's what the error shows. You can see https://devsi.api.crm.dynamics.com/devsi.api.crm.dynamics.com/
<- devsi.api.crm.dynamics.com
in there twice.
@AleksandrRogov Yes I also see this issue
My credentials
DYNAMICS_CLIENT_ID="---" DYNAMICS_CLIENT_SECRET="---" DYNAMICS_INSTANCE_URI="https://devsi.api.crm.dynamics.com/" DYNAMICS_AUTHORITY_URL="https://login.microsoftonline.com/d0f7f33f-8d1f-4ac0-bccd-2ecda8bf422b"
Code Snippet
import * as MSAL from '@azure/msal-node';
import { ConfigService } from '@nestjs/config';
import { DynamicsWebApi } from 'dynamics-web-api';
import { InternalServerErrorException, Injectable } from '@nestjs/common';
import { LoggerService } from '@app/shared/logger';
@Injectable()
export class DynamicsService {
private dynamicsWebApi: DynamicsWebApi;
constructor(
private readonly loggerService: LoggerService,
private readonly configService: ConfigService
) {
this.initializeDynamicsWebApi();
}
private initializeDynamicsWebApi() {
const clientId = this.configService.get<string>('DYNAMICS.CLIENT_ID');
const instanceUri = this.configService.get<string>('DYNAMICS.INSTANCE_URI');
const clientSecret = this.configService.get<string>('DYNAMICS.CLIENT_SECRET');
const authorityUrl = this.configService.get<string>('DYNAMICS.AUTHORITY_URL');
const msalConfig = {
auth: {
knownAuthorities: ['login.microsoftonline.com'],
clientSecret: clientSecret,
authority: authorityUrl,
clientId: clientId
}
};
const cca = new MSAL.ConfidentialClientApplication(msalConfig);
this.dynamicsWebApi = new DynamicsWebApi({
onTokenRefresh: async () => {
try {
const result = await cca.acquireTokenByClientCredential({
scopes: [`${instanceUri}/.default`]
});
return result.accessToken;
} catch (ex) {
this.loggerService.error(`[${this.constructor.name}.initializeDynamicsWebApi]`, ex);
return null;
}
},
serverUrl: instanceUri
});
}
async retrieveContacts() {
try {
this.loggerService.trace(`[${this.constructor.name}.retrieveContacts]`);
const request = {
collection: 'contacts',
select: ['contactid'],
maxPageSize: 10,
count: true
};
const firstPage = await this.dynamicsWebApi.retrieveMultiple(request);
console.log(firstPage.value[0]);
const nextPageLink = firstPage['@odata.nextLink'];
console.log(nextPageLink);
//removing 'select' and 'count' from a request because they get duplicated in the result url
const nextPagesRequest = {
maxPageSize: request.maxPageSize,
collection: request.collection
};
const secondPage = await this.dynamicsWebApi.retrieveMultiple(nextPagesRequest, nextPageLink);
console.log(secondPage.value[0]);
return firstPage;
} catch (ex) {
this.loggerService.error(`[${this.constructor.name}.retrieveContacts]`, ex);
throw new InternalServerErrorException(ex);
}
}
}
@ArtashMardoyanS I will try to reproduce this locally.
Nevermind, I saw that you mentioned it in the reply above. Thanks.
@ArtashMardoyanS please remove a slash "/" at the end of your DYNAMICS_INSTANCE_URI
for now. That slash seems to cause an issue.
DYNAMICS_INSTANCE_URI="https://devsi.api.crm.dynamics.com"
I will work on the fixes. Thank you for submitting the bugs.
@ArtashMardoyanS I fixed the issues in v.2.1.2. It can be downloaded from npm. If you have any issues with an update let me know. Thanks!
@AleksandrRogov thanks, I'll check and let you know
@AleksandrRogov We updated the version to "v.2.1.2" and now it is working thank you so much you helping us.
DynamicsWebApi version For example: ^2.1.1
Describe the bug '@odata.nextLink' when we use for the second parameter in "retrieveMultiple" function it returns an error
Actual result The URI 'https://devsi.api.crm.dynamics.com/devsi.api.crm.dynamics.com/api/data/v9.2/contacts?$select=contactid&$count=true&$skiptoken= ?$select=contactid&$count=true' is not valid because it is not based on 'https://devsi.api.crm.dynamics.com/api/data/v9.2/'.
Code Snippet