Hi abp zero folks,
We are having this issue where the dateformat works fine in our local machine where the code is. But when its deployed to Azure it does not work. We have this code in the angular client side in AppPreBootstrap.ts file as suggested by one of the support folks. We want to get date displayed in canada format when the browser settings are set to canada(English language)
let locale = window.navigator.language; moment.locale(locale); (window as any).moment.locale(locale);
When we debug in azure it shows the correct browser language set . But the dateformat in the grid does not change to the language set in the browser. so kind of when we run window.navigator.language in console for the app deployed in azure it shows the correct language. We have set this in the grid. momentFormat:'L LTS'
Can you please help ?
I am sending you our local credentials for the app
Username : user123456
Password : Qwerty123$
Here's the url for the application : https://demoqa.assurantlogistics.com/
Here's the page you can directly go to this url if the page does not show up when you login ... https://demoqa.assurantlogistics.com/app/main/returnManagement/returns
-- We are talking about the creation Date column in the returns page grid which needs to be shown according to the user browser language format
Here are the Print modal pop up ts and HTML files . Also attaching the TS and HTML PAge from where the Print label modal is called : -- Here is the Print Label modal TS file below
import { Component, OnInit, ViewChild, Injector, Input } from '@angular/core';
import { ModalDirective } from 'ngx-bootstrap';
import { AppComponentBase } from '@shared/common/app-component-base';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { HttpClient } from '@angular/common/http';
import { AppConsts } from '@shared/AppConsts';
@Component({
selector: 'printLabelModal',
templateUrl: './printLabel-modal.component.html',
styleUrls: ['./printLabel-modal.component.css']
})
export class PrintLabelModalComponent extends AppComponentBase implements OnInit {
@Input('filename') filename: string;
@ViewChild('createOrEditModal', { static: false }) modal: ModalDirective;
safeUrl: SafeResourceUrl;
uploadUrl: string;
getUrl: string;
openPdfInNewTab: boolean = false;
pdfUrl: string;
constructor(
injector: Injector,
private sanitizer: DomSanitizer,
private _httpClient: HttpClient
) {
super(injector);
this.uploadUrl = AppConsts.remoteServiceBaseUrl + '/api/Orders/UploadFileToBlobStorage';
this.getUrl = AppConsts.remoteServiceBaseUrl + '/api/Orders/GetFileFromBlobStorage/';
let isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
if (navigator.userAgent.match(/Android|webOS|iPhone|iPod|iPad|Blackberry/i) || isSafari) {
this.openPdfInNewTab = true;
}
}
ngOnInit() {
}
show(pdf: any) {
let labelData = pdf.output('bloburl');
this.labelURL(labelData);
this.viewPdf();
}
labelURL(label: any) {
setTimeout(() => {
this.pdfUrl = label;
this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(label);
}, 0);
}
showPdf(pdf: string) {
this.labelURL(pdf);
this.viewPdf();
}
close(): void {
this.modal.hide();
}
viewPdf() {
setTimeout(() => {
if (this.pdfUrl !== null && this.pdfUrl !== undefined && this.openPdfInNewTab) {
window.open().location.href = this.pdfUrl;
}
else {
this.modal.show();
}
}, 0);
}
uploadPdf(pdf: any, fileName: string): void {
let blob = pdf.output('blob');
let formData = new FormData();
formData.append('pdf', blob, fileName);
this._httpClient
.post<any>(this.uploadUrl, formData)
.subscribe();
}
getPdf(containerName: string, fileName: string) {
this._httpClient
.get(this.getUrl + containerName + '/' + fileName, { responseType: 'blob' })
.subscribe(res => {
let file = new Blob([res], { type: res.type });
let url = window.URL.createObjectURL(file);
this.labelURL(url);
this.viewPdf();
});
}
}
---- HTML FILE FOR PRINT MODAL POP UP
<div bsModal #createOrEditModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="createOrEditModal" [config]="{backdrop: 'static', keyboard: false}">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="embed-responsive embed-responsive-1by1">
<iframe class="embed-responsive-item" type="application/pdf" [src]='this.safeUrl' id="labelFrame" framemargin="0"
class="frame" width="100%">
</iframe>
</div>
<div class="text-center">
<button type="button" class="btn btn-primary blue m-2" (click)="close()">{{l("Close")}}</button>
</div>
</div>
</div>
</div>
---- THE PRINT LABEL MODAL IS BEING CALLED FROM THIS PAGE :
<div [@routerTransition]>
<div class="kt-subheader kt-grid__item">
<div class="kt-subheader__main">
<h3 class="kt-subheader__title">
<span>{{l("Vouchers")}} - {{ storeDisplayName }} </span>
</h3>
<button (click)="openReceipt(record.offerNumber)" class="btn btn-primary" type="submit"><i class="flaticon-search-1"></i></button>
</div>
</div>
<printLabelModal #printLabelModal filename="{{fileName}}"></printLabelModal>
<div [busyIf]="voucherIsLoading" *ngIf="voucherIsLoading"></div>
</div>
--- HERE 's the TS FILE FOR THAT
import { Component, OnInit, Injector, ViewEncapsulation, ViewChild, Input, ElementRef, ChangeDetectorRef, AfterViewInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Table } from 'primeng/components/table/table';
import { Paginator } from 'primeng/components/paginator/paginator';
import { LazyLoadEvent } from 'primeng/components/common/lazyloadevent';
import { OfferServiceProxy, GetAllVoucherViewDto } from '@shared/service-proxies/service-proxies';
import * as _ from 'lodash';
import { AppComponentBase } from '@shared/common/app-component-base';
import { OrganizationUnitsComboboxService } from '@app/main/header/organization-units-combobox/organization-units-combobox.service';
import { appModuleAnimation } from '@shared/animations/routerTransition';
import * as moment from 'moment';
import { formatDate } from '@angular/common';
import { PrintLabelModalComponent } from '@app/main/shared/printLabel/printLabel-modal.component';
import { AppConsts } from '@shared/AppConsts';
@Component({
templateUrl: './voucher.component.html',
encapsulation: ViewEncapsulation.None,
animations: [appModuleAnimation()]
})
export class VoucherComponent extends AppComponentBase implements OnInit {
@ViewChild('dataTable', { static: true }) dataTable: Table;
@ViewChild('paginator', { static: true }) paginator: Paginator;
@ViewChild('printLabelModal', { static: true }) printLabelModal: PrintLabelModalComponent;
storeDisplayName: string;
isValid = true;
voucherIsLoading = false;
advancedFiltersAreShown = false;
filterText = '';
imeiFilter = '';
voucherNumberFilter = '';
rmaNumberFilter = '';
commentFilter = '';
isDeletedFilter = -1;
maxCreationTimeFilter: moment.Moment;
minCreationTimeFilter: moment.Moment;
maxModificationTimeFilter: moment.Moment;
minModificationTimeFilter: moment.Moment;
organizationUnitDisplayNameFilter = '';
orderStatusNameFilter = '';
userNameFilter = '';
orderTypeCodeFilter = '';
trackingNumberFilter = '';
shipmentTrackingNumberFilter = '';
//start dynamic columns - will come from backend
detailResults: any;
returnorderId = '';
orderNumber: string;
fileName: string;
shippingResults: any;
labelImage: string;
lithiumImage: string;
labelType: string;
trackingNumber: string;
labelIsLoading: boolean;
returnOrderRma: string;
returnOrderDetail: any;
organizationUnitId: number;
userNameFeature = JSON.parse(abp.features.getValue('App.UserNameFeature'));
constructor(
injector: Injector,
private _organizationUnitsComboboxService: OrganizationUnitsComboboxService,
private _offerService: OfferServiceProxy,
) {
super(injector);
}
nextFrame(): void {
if (this._organizationUnitsComboboxService === undefined || this._organizationUnitsComboboxService.selectedOrganizationUnit === undefined) {
if(AppConsts.showAbpNotifications) abp.notify.info(this.l('LoadVoucherData'));
setTimeout(() => this.nextFrame(), 1000);
} else {
this.storeDisplayName = this._organizationUnitsComboboxService.selectedOrganizationUnit.displayName;
this.organizationUnitId = this._organizationUnitsComboboxService.selectedOrganizationUnit.id;
this.initialize();
}
}
ngOnInit(): void {
this.nextFrame();
this._organizationUnitsComboboxService.events$.forEach(event => {
this.storeDisplayName = event.displayName;
this.organizationUnitId = event.id;
});
}
// initial loading of data
initialize() {
}
openReceipt(offerNumber: string): void {
this.printLabelModal.getPdf('receipts', offerNumber + '.pdf');
}
}
Hi Maliming,
I have tried upgrading Sweetalert2 to v8.14.0 and also the latest current version v9.15.1. But, still the problem exists.
Hi ,
We are having Multi Page Application built with Asp.Net Core and Angular 8. We keep on getting this error a shown below. On an primeng grid column we have a print button which call the print.modal popup which causes this issues. The modal popup being used is similar to the ones you use being used by abp(on organization-units- add-role-modal.component.ts). Can you please guide on how to reolve this error.
ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'null' Error: Cannot match any routes. URL Segment: 'null' at e.noMatchError (main.d82dd10c4ffbd073ef7f.js:1) at t.selector (main.d82dd10c4ffbd073ef7f.js:1) at t.error (main.d82dd10c4ffbd073ef7f.js:1) at t._error (main.d82dd10c4ffbd073ef7f.js:1) at t.error (main.d82dd10c4ffbd073ef7f.js:1) at t._error (main.d82dd10c4ffbd073ef7f.js:1) at t.error (main.d82dd10c4ffbd073ef7f.js:1) at t._error (main.d82dd10c4ffbd073ef7f.js:1) at t.error (main.d82dd10c4ffbd073ef7f.js:1) at t._error (main.d82dd10c4ffbd073ef7f.js:1) at D (polyfills.13a319357725c84c3bd3.js:1) at D (polyfills.13a319357725c84c3bd3.js:1) at polyfills.13a319357725c84c3bd3.js:1 at t.invokeTask (polyfills.13a319357725c84c3bd3.js:1) at Object.onInvokeTask (main.d82dd10c4ffbd073ef7f.js:1) at t.invokeTask (polyfills.13a319357725c84c3bd3.js:1) at e.runTask (polyfills.13a319357725c84c3bd3.js:1) at d (polyfills.13a319357725c84c3bd3.js:1)
Thanks.
Hi Abp Zero,
We are having Multi Page Application built with Asp.Net Core and Angular 8 and using abp.notify feature to display messages(set timeout to 5000 ms) throughout the website. When a message is displayed in one page and we route to a different page in less than 5000 ms, we are getting console error(below) and greyout page and unable to perform any action until page refresh. Please help us in handling this behavior and let us know if there is a possibility to close abp.notify messages before the timeout in ngOnDestroy() when switching between components.
Thanks.
ERROR TypeError: Cannot read property 'removeEventListener' of undefined at removePopupAndResetState (scripts.js:33343) at handlePopupAnimation (scripts.js:33417) at SweetAlert.close (scripts.js:33386) at dismissWith (scripts.js:34217) at scripts.js:34278 at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (polyfills.js:12578) at Object.onInvokeTask (vendor.js:71493) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (polyfills.js:12577) at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (polyfills.js:12350) at push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask (polyfills.js:12653)
thanks for you response. I do get the correct browser setting when i work on my local devleopment machine. and also the date format changes according to the browser settings on the ngprime grid locally .But the issue basically happens in our QA and Prod Environments. We do use utcprovider. Also is there any feature we need to enable in Qa and prod environment to make the date format work correctly based on browser settings ?
Hi , We tried to reach you previously for this issue and you suggested to use the below code in AppPreBoostrap.ts file . But not sure we tried to change the Browser to use canada format but it still showed US Data format. I site is is in prod and we need your help urgently. let locale = window.navigator.language; moment.locale(locale); (window as any).moment.locale(locale);
I have attached the entire code code from our AppPreBoostrap.ts file. Please help ...
import { UtilsService } from '@abp/utils/utils.service';
import { CompilerOptions, NgModuleRef, Type } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppAuthService } from '@app/shared/common/auth/app-auth.service'; import { AppConsts } from '@shared/AppConsts'; import { SubdomainTenancyNameFinder } from '@shared/helpers/SubdomainTenancyNameFinder'; import * as moment from 'moment-timezone'; import * as _ from 'lodash'; import { UrlHelper } from './shared/helpers/UrlHelper'; import { XmlHttpRequestHelper } from '@shared/helpers/XmlHttpRequestHelper'; import { DynamicResourcesHelper } from '@shared/helpers/DynamicResourcesHelper'; import { environment } from './environments/environment'; import { LocaleMappingService } from '@shared/locale-mapping.service';
export class AppPreBootstrap {
static run(appRootUrl: string, callback: () => void, resolve: any, reject: any): void {
AppPreBootstrap.getApplicationConfig(appRootUrl, () => {
if (UrlHelper.isInstallUrl(location.href)) {
AppPreBootstrap.loadAssetsForInstallPage(callback);
return;
}
const queryStringObj = UrlHelper.getQueryParameters();
if (queryStringObj.redirect && queryStringObj.redirect === 'TenantRegistration') {
if (queryStringObj.forceNewRegistration) {
new AppAuthService().logout();
}
location.href = AppConsts.appBaseUrl + '/account/select-edition';
} else if (queryStringObj.impersonationToken) {
AppPreBootstrap.impersonatedAuthenticate(queryStringObj.impersonationToken, queryStringObj.tenantId, () => { AppPreBootstrap.getUserConfiguration(callback); });
} else if (queryStringObj.switchAccountToken) {
AppPreBootstrap.linkedAccountAuthenticate(queryStringObj.switchAccountToken, queryStringObj.tenantId, () => { AppPreBootstrap.getUserConfiguration(callback); });
} else {
AppPreBootstrap.getUserConfiguration(callback);
}
});
}
static bootstrap<TM>(moduleType: Type<TM>, compilerOptions?: CompilerOptions | CompilerOptions[]): Promise<NgModuleRef<TM>> {
return platformBrowserDynamic().bootstrapModule(moduleType, compilerOptions);
}
private static getApplicationConfig(appRootUrl: string, callback: () => void) {
let type = 'GET';
let url = appRootUrl + 'assets/' + environment.appConfig;
let customHeaders = [
{
name: 'Abp.TenantId',
value: abp.multiTenancy.getTenantIdCookie() + ''
}];
XmlHttpRequestHelper.ajax(type, url, customHeaders, null, (result) => {
const subdomainTenancyNameFinder = new SubdomainTenancyNameFinder();
let tenancyName = subdomainTenancyNameFinder.getCurrentTenancyNameOrNull(result.appBaseUrl);
//Custom changes for Okta Host widget--106375
if(tenancyName.toLowerCase().includes("host")) {tenancyName="Default"; }
// CUSTOM ADDITION HERE
let getTenantIdURL = result.remoteServiceBaseUrl + '/api/services/app/Account/IsTenantAvailable';
let getTenantIdData = {tenancyName: tenancyName};
XmlHttpRequestHelper.ajax('POST', getTenantIdURL, null, JSON.stringify(getTenantIdData), (tenantResult) => {
abp.multiTenancy.setTenantIdCookie(tenantResult.result.tenantId);
AppConsts.appBuildNumber = result.appBuildNumber;
AppConsts.appBaseUrlFormat = result.appBaseUrl;
AppConsts.remoteServiceBaseUrlFormat = result.remoteServiceBaseUrl;
AppConsts.localeMappings = result.localeMappings;
AppConsts.azureCdnUrl=result.azureCdnUrl;
if (tenancyName == null) {
AppConsts.appBaseUrl = result.appBaseUrl.replace(AppConsts.tenancyNamePlaceHolderInUrl + '.', '');
//AppConsts.remoteServiceBaseUrl = result.remoteServiceBaseUrl.replace(AppConsts.tenancyNamePlaceHolderInUrl + '.', '');
} else {
AppConsts.appBaseUrl = result.appBaseUrl.replace(AppConsts.tenancyNamePlaceHolderInUrl, tenancyName);
//AppConsts.remoteServiceBaseUrl = result.remoteServiceBaseUrl.replace(AppConsts.tenancyNamePlaceHolderInUrl, tenancyName);
}
AppConsts.remoteServiceBaseUrl = result.remoteServiceBaseUrl;
callback();
});
});
}
private static getCurrentClockProvider(currentProviderName: string): abp.timing.IClockProvider {
if (currentProviderName === 'unspecifiedClockProvider') {
return abp.timing.unspecifiedClockProvider;
}
if (currentProviderName === 'utcClockProvider') {
return abp.timing.utcClockProvider;
}
return abp.timing.localClockProvider;
}
private static impersonatedAuthenticate(impersonationToken: string, tenantId: number, callback: () => void): void {
abp.multiTenancy.setTenantIdCookie(tenantId);
const cookieLangValue = abp.utils.getCookieValue('Abp.Localization.CultureName');
let requestHeaders = {
'.AspNetCore.Culture': ('c=' + cookieLangValue + '|uic=' + cookieLangValue),
'Abp.TenantId': abp.multiTenancy.getTenantIdCookie()
};
XmlHttpRequestHelper.ajax(
'POST',
AppConsts.remoteServiceBaseUrl + '/api/TokenAuth/ImpersonatedAuthenticate?impersonationToken=' + impersonationToken,
requestHeaders,
null,
(response) => {
let result = response.result;
abp.auth.setToken(result.accessToken);
AppPreBootstrap.setEncryptedTokenCookie(result.encryptedAccessToken);
location.search = '';
callback();
}
);
}
private static linkedAccountAuthenticate(switchAccountToken: string, tenantId: number, callback: () => void): void {
abp.multiTenancy.setTenantIdCookie(tenantId);
const cookieLangValue = abp.utils.getCookieValue('Abp.Localization.CultureName');
let requestHeaders = {
'.AspNetCore.Culture': ('c=' + cookieLangValue + '|uic=' + cookieLangValue),
'Abp.TenantId': abp.multiTenancy.getTenantIdCookie()
};
XmlHttpRequestHelper.ajax(
'POST',
AppConsts.remoteServiceBaseUrl + '/api/TokenAuth/LinkedAccountAuthenticate?switchAccountToken=' + switchAccountToken,
requestHeaders,
null,
(response) => {
let result = response.result;
abp.auth.setToken(result.accessToken);
AppPreBootstrap.setEncryptedTokenCookie(result.encryptedAccessToken);
location.search = '';
callback();
}
);
}
private static getUserConfiguration(callback: () => void): any {
const cookieLangValue = abp.utils.getCookieValue('Abp.Localization.CultureName');
const token = abp.auth.getToken();
let requestHeaders = {
'.AspNetCore.Culture': ('c=' + cookieLangValue + '|uic=' + cookieLangValue),
'Abp.TenantId': abp.multiTenancy.getTenantIdCookie(),
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET,PUT,POST'
};
if (token) {
requestHeaders['Authorization'] = 'Bearer ' + token;
}
return XmlHttpRequestHelper.ajax('GET', AppConsts.remoteServiceBaseUrl + '/api/services/app/UiCustomizationSettings/GetAll', requestHeaders, null, (response) => {
let result = JSON.parse(response).result;
_.merge(abp, result);
abp.clock.provider = this.getCurrentClockProvider(result.clock.provider);
let locale = window.navigator.language;
moment.locale(locale);
(window as any).moment.locale(locale);
if (abp.clock.provider.supportsMultipleTimezone) {
moment.tz.setDefault(abp.timing.timeZoneInfo.iana.timeZoneId);
(window as any).moment.tz.setDefault(abp.timing.timeZoneInfo.iana.timeZoneId);
} else {
moment.fn.toJSON = function () {
return this.locale('en').format();
};
moment.fn.toISOString = function () {
return this.locale('en').format();
};
}
abp.event.trigger('abp.dynamicScriptsInitialized');
AppConsts.noDirectAccessWorkflowPages = JSON.parse(abp.setting.get('App.UiManagement.Workflow.NoDirectAccessPages'));
AppConsts.recaptchaSiteKey = abp.setting.get('Recaptcha.SiteKey');
AppConsts.subscriptionExpireNootifyDayCount = parseInt(abp.setting.get('App.TenantManagement.SubscriptionExpireNotifyDayCount'));
DynamicResourcesHelper.loadResources(callback);
});
}
private static setEncryptedTokenCookie(encryptedToken: string) {
new UtilsService().setCookieValue(AppConsts.authorization.encrptedAuthTokenName,
encryptedToken,
new Date(new Date().getTime() + 365 * 86400000), //1 year
abp.appPath
);
}
private static loadAssetsForInstallPage(callback) {
abp.setting.values['App.UiManagement.Theme'] = 'default';
abp.setting.values['default.App.UiManagement.ThemeColor'] = 'default';
DynamicResourcesHelper.loadResources(callback);
}
}
Also in the prime ng grid i am adding the date format like this for the column
<ng-template pTemplate="body" let-record="$implicit"> <tr [ngClass]="record.selected && !isShow ? 'validated' :(record.scannedByotherUser && !isShow ? 'validatedByOthers' : '')"> <td ngFor="let col of shipOutCols" [hidden]="!col.isVisible"> {{col.field.includes('Time') || col.field.includes('Date') ? ** (record[col.field] | momentFormat:'L LTS'):record[col.field]}}* </td>
Thank you again maliming. Let me close this thread:)
Thank you Aaron! That's very detailed and helpful. Wondering why I forgot the IsDefault() at the first place. It's working now!
Thank you so much maliming!! You're the savior. Would it be abp version 4.11?
Best regards,