setting defaultValue to p-multiselect - html

my code looks like below
export class LkBoardStatus {
id : number = 0;
descr : string = '';
}
component.ts
//...
lkBoardStatusList: LkBoardStatus[] = [];
selectedStatus: LkBoardStatus = new LkBoardStatus;
ngOnInit():void {
this.loadBoardStatusList();
../
}
loadBoardStatusList(){
this.boardService.loadBoardStatus().subscribe( posts =>{
this.data = posts;
console.log('loadBoardStatusList',this.data);
},
error => {
console.log('loadBoardStatusList - error',error);
this._errorService.handleError(error);
},
() => {
this.lkBoardStatusList = this.data.boardStatusLi;
for(let i=0; i<this.lkBoardStatusList.length; i++){
if(this.lkBoardStatusList[i].id == 70){
this.selectedStatus = this.lkBoardStatusList[i];
}
}
console.log(this.selectedStatus);
});
}
Here I have selectedStatus which is assigned a value of '70' as in for loop.
My comopnent.html is below
<th *ngSwitchCase="'statusObj'" [colSpan] = "2" style="text-align:center">
<p-multiSelect [options]="lkBoardStatusList" optionLabel="descr" [(ngModel)]="selectedStatus" defaultLabel="Select" (onChange)="dt.filter($event.value, col.field, 'in')"></p-multiSelect>
The inspect element gives me the correct object for selectedStatus but onLoad the value is not getting defaulted to 70. Where am I going wrong? Suggestions please.TIA

selectedStatus must be an array.
Try to replace
for(let i=0; i<this.lkBoardStatusList.length; i++){
if(this.lkBoardStatusList[i].id == 70){
this.selectedStatus = this.lkBoardStatusList[i];
}
}
with
this.selectedStatus = this.lkBoardStatusList.filter(item => item.id == 70);

Related

Getting latest Date in Angular9

I'm trying to get the last date in the request notes and show it with console.log(), i used console.log(this.changeRequest.reduce((a, b) => (a.ModificationDate > b.ModificationDate ? a : b))); to show the latest date on update and what it show is not the latest date, here is some screens to show the result :
Here is the changeRequest Modal :
export class ChangeRequestModel {
CRId: string;
RId: string;
UserName: string;
Comment: string;
Action: string;
Type: string;
Modified: boolean;
Deleted: boolean;
ActionDate: Date;
ModificationDate: Date;
Request: RequestViewmodel;
constructor(changeRequest?) {
changeRequest = changeRequest || {};
this.CRId = changeRequest.CRId || "0000000001";
this.RId = changeRequest.RId || "";
this.UserName = changeRequest.UserName || "";
this.Comment = changeRequest.Comment;
this.Action = changeRequest.Action;
this.Type = changeRequest.Type;
this.Modified = changeRequest.Modified;
this.Deleted = changeRequest.Deleted;
this.ActionDate = changeRequest.ActionDate;
this.ModificationDate = changeRequest.ModificationDate;
this.Request = changeRequest.Request;
}
}
This is changeRequest type : changeRequest: ChangeRequestModel[];
This is the getRequest in the component.ts :
getRequestInfo() {
this._requestService.getRequestById(this.requestId).subscribe(
(res: any) => {
if (res) {
this.requestInfo = res;
this.getChangeRequestInfo();
this.PId = res.PId;
this._jobPositionService
.GeJobPositionById(this.PId)
.subscribe((res: any) => {
this.jobPositionInfo = res;
});
}
},
(err) => {
this._snotify.error("Error loading request informations");
}
);
}
This is the getChangeRequest in the component.ts :
getChangeRequestInfo() {
this._changeRequestService.getChangeRequestsByRId(this.requestId).subscribe(
(res: any) => {
this.changeRequest = res.changeRequestList;
if(this.requestInfo.RequestStatus.Text == "Closed")
{
for (let i = 0; i < this.changeRequest?.length; i++) {
var str = this.changeRequest[i]?.Comment ;
var commentPattern = str?.match(/(?:closed|Closed)+$/gm);
console.log(this.changeRequest[i].ModificationDate);
if (commentPattern?.length == null) {
console.log(str);
console.log("no match");
} else if (commentPattern?.length > 0 && this.requestInfo.RequestStatus.Text != "Closed") {
console.log(str);
console.log("Request not closed yet");
}
else if (commentPattern?.length > 0 && this.requestInfo.RequestStatus.Text == "Closed") {
console.log(str);
console.log("match");
console.log(this.changeRequest.reduce((a, b) => (a.ModificationDate > b.ModificationDate ? a : b)));
}
}
}
}
);
}
For some requests it show me a correct result and for some requests it shows me a wrong result like the one shown before, can anyone help me ?

How do I do a recursion over objects of unknown depth in Typescript?

I have a JSON file with a category structure of unknown depth. I want to make sure all pages can be accessed. I established three nested calls, but I think it would be better to recursion here. Unfortunately, I have no experience with Typescript regarding recursion. Can someone be so kind as to help me put the logic into a function I can call?
test.setTimeout(28800000); // 8 hours max.
// console.log(ofcJSON)
for (let i = 0; i < ofcJSON.items.length; i++) {
let currentPage = ofcJSON.items[i].link
console.log(currentPage)
if (!currentPage.startsWith("http")) await page.goto(currentPage)
if (ofcJSON.items[i].items != null) {
for (let j = 0; j < ofcJSON.items[i].items!.length; j++) {
let currentPage1 = ofcJSON.items[i].items![j].link
console.log(currentPage1)
if (!currentPage1.startsWith("http")) await page.goto(currentPage1)
if (ofcJSON.items[i].items![j].items != null) {
for(let k = 0; k < ofcJSON.items[i].items![j].items!.length; k++) {
let currentPage2 = ofcJSON.items[i].items![j].items![k].link
console.log(currentPage2)
if (!currentPage2.startsWith("http")) await page.goto(currentPage2)
if (ofcJSON.items![i].items![j].items![k].items != null) {
for(let l = 0; l < ofcJSON.items[i].items![j].items![k].items!.length; l++) {
let currentPage3 = ofcJSON.items[i].items![j].items![k].items![l].link
console.log(currentPage3)
if (!currentPage3.startsWith("http")) await page.goto(currentPage3)
}
}
}
}
}
}
}
});
The JSON has 1 items object, which in turn can have 1 items object. This is optional. I don't know the depth.
I sketched an implementation which compiles and runs in the typescript playground as below (click on Run top left in the playground)...
type HttpLink = `http{'s'|''}://${string}`;
function isHttpLink(link: string): link is HttpLink {
return !!link.match(/^https?:\/\//);
}
type Link = HttpLink | string;
interface Item {
link: Link;
items?: Item[];
}
async function goto(link: HttpLink) {
console.log(`Ran goto on ${link}`);
}
async function visitItemAndDescendants(ancestor: Item) {
const { link, items } = ancestor;
if (isHttpLink(link)) {
await goto(link);
}
if (items) {
for (const item of items) {
visitItemAndDescendants(item);
}
}
}
{
const exampleItem: Item = {
link: "https://my.url",
items: [
{
link: "not http",
items: [
{
link:"http://insecure.url"
},
{
link:"https://another.url"
}
],
},
],
};
visitItemAndDescendants(exampleItem)
}
Thanks to your help and the help of a colleague I have solved the problem as follows:
import { Page, test } from '#playwright/test';
import fetch from "node-fetch";
test.use({
baseURL: "https://www.myUrl.de/"
})
const links: string[] = [];
interface Item {
link: string;
items?: Item[];
}
async function getLinks(item: Item): Promise<void> {
if (item.items && item.items.length > 0) {
for (let i = 0; i < item.items.length; i++) {
let currentItem = item.items[i];
if (currentItem.link && currentItem.link.length > 0) {
links.push(currentItem.link);
if (currentItem.items && currentItem.items.length > 0)
getLinks(currentItem);
}
}
}
}
test('test', async ({ page }) => {
test.setTimeout(1560000); // 26 minutes max.
const ofcJSON = await fetch('https://www.myUrl.de/ofcJSON')
.then((response) => response.json())
.then((item) => {
return item.items
})
// console.log(ofcJSON);
ofcJSON.forEach(element => {
getLinks(element);
});
var maximumNumberOfLinksToCheck = 10;
var delta = Math.floor(links.length / maximumNumberOfLinksToCheck);
for (let i = 0; i < links.length; i = i + delta) {
console.log("Checking page: " + links[i])
await (page.goto(links[i]));
}
});

I'm trying to create a memory game where an expanding list of numbers is shown in ionic and angular and the user has to type in the answer

The way that I am doing it is that I want each of the numbers to appear then disappear. I have tried a lot of options but only the last number ends up showing when there are two or more numbers in the array. I suspect it has something to do with the for loop, but there does not seem to be a way around it.
Here is my typescript code for the generate numbers function:
generateNumbers() {
let numbersArray = new Promise<number[]>((resolve, reject) => {
let numberArray: number[] = []
for (let i = 0; i < this.level; i++) {
this.animationCtrl.create()
.addElement(this.currentNum.nativeElement)
.duration(500)
.iterations(1)
.fromTo('opacity', '1', '0.05').play()
.then(func => {
let randomnum = Math.floor(Math.random() * 9)
numberArray.push(randomnum)
this.currentIndex = i
this.currentNumber = randomnum
this.parsedCurrentNumber = JSON.parse(JSON.stringify(this.currentNumber))
}).then(func => {
this.animationCtrl.create()
.addElement(this.currentNum.nativeElement)
.duration(500)
.iterations(1)
.fromTo('opacity', '0.05', '1').play()
}).then(func => {
if (i === this.level - 1) {
resolve(numberArray)
}
})
}
})
return numbersArray
}
Here are my variable declarations and injections:
#ViewChild('currentNumber', { read: ElementRef, static: true}) currentNum: ElementRef;
level: number = 1;
levelExp: number = 1;
gameHasBegun = false;
paused = false;
numbersArray: number[] = [];
answer: string;
wrongcount: number = 0;
wrong = false;
lost = false;
currentIndex: number = 0
currentNumber: number;
parsedCurrentNumber: string;
constructor(
private router: Router,
private menu: MenuController,
private animationCtrl: AnimationController ) { }
Here is how I call my generate function:
this.generateNumbers().then(
(val) => this.numbersArray = val
)
Here is my HTML Code for the part where the numbers should be shown, but instead only one number is shown when I have two or more numbers in my array:
<ion-content #currentNumber>
<ion-label class="ion-text-center" >
<h1>{{ parsedCurrentNumber }}</h1>
</ion-label>
</ion-content>
Look at the following stackblitz.
https://stackblitz.com/edit/ionic-79e1rn
You basically need to loop through your array with a timeout.
ionViewDidEnter(){
this.runSeries(0);
}
runSeries(i){
if(i < this.nums.length){
setTimeout(() => {
this.lastNum = this.nums[i];
i++;
this.runSeries(i);
}, 1000)
}
}
and bind lastNum in your template.

state district json binding react

I want to display display list of districts from the json, receiving the following error
'TypeError: suggestion.districts.slice(...).toLowerCase is not a function'
json file.
How can I get the list of districts details, so that I can perform autocomplete using downshift?
any help appreciated.
json format
{
"states":[
{
"state":"Andhra Pradesh",
"districts":[
"Anantapur",
"Chittoor",
"East Godavari",
]
},
{
"state":"Arunachal Pradesh",
"districts":[
"Tawang",
"West Kameng",
"East Kameng",
]
},
}
component
import React, { Component } from 'react'
import statedist from "./StateDistrict.json";
const suggestions = statedist.states;
/*.... */
function getSuggestions(value, { showEmpty = false } = {}) {
// const StatesSelected=props.StatesSelected;
const inputValue = deburr(value.trim()).toLowerCase();
const inputLength = inputValue.length;
let count = 0;
//console.log(StatesSelected)
return inputLength === 0 && !showEmpty
? []
: suggestions.filter(suggestion => {
const keep =
count < 5 &&
suggestion.districts.slice(0, inputLength).toLowerCase() === inputValue;
if (keep) {
count += 1;
}
return keep;
});
}
function renderSuggestion(suggestionProps) {
const {
suggestion,
index,
itemProps,
highlightedIndex,
selectedItem
} = suggestionProps;
const isHighlighted = highlightedIndex === index;
const isSelected = (selectedItem || "").indexOf(suggestion.districts) > -1;
return (
<MenuItem
{...itemProps}
key={suggestion.districts[0]}
selected={isHighlighted}
component="div"
style={{
fontWeight: isSelected ? 500 : 400
}}
>
{suggestion.districts[0]} -- how can I get all the values instead of one here
</MenuItem>
);
}
class autoCompleteState extends Component {
constructor(props) {
super(props);
this.state = {
SelectedState:'',
}
// this.showProfile = this.showProfile.bind(this)
}
setSelectedDistrict = (newState) => {
this.setState({ SelectedState: newState });
console.log(newState)
this.props.onDistrictSelected(newState);
}
render() {
const { classes, } = this.props;
console.log(this.state.SelectedState)
const StatesSelected=this.props.StateList;
return (
<div>
<DownshiftMultiple
classes={classes}
setSelectedDistrict={this.setSelectedDistrict}
StatesSelected={StatesSelected}
/>
</div>
)
}
}
export default withStyles(Styles)(autoCompleteState);
I want the district details to come as suggestion like state in the below image
Currently, you are doing this:
suggestion.districts.slice(0, inputLength).toLowerCase() === inputValue;
This is throwing an error because .slice is copying inputLength items from your districts array and then trying to call .toLowerCase() on that array.
If I understand correctly, you are trying to filter your districts according to the inputValue. One way of doing this would be to use reduce on the districts array like this:
suggestion.districts.reduce((acc,curr)=>curr.substring(0,inputLength)===inputValue?[...acc,curr.substring(0,inputLength)]:acc, [])
If you only want the first 5 then you can slice the result of this:
suggestion.districts.reduce((acc,curr,index)=>index<5&&curr.substring(0,inputLength)===inputValue?[...acc,curr.substring(0,inputLength)]:acc, [])

kendo treeview with new data source

Ok, so I have this situation here:
A CSHTML view with a kendo tree in it:
#(Html.Kendo().TreeView()
.Name("treeview")
.DataTextField("Name")
.DataSource(d => d.Read(r => r.Action("WorkedHours", "TaskManager")))
.Events(e => e.Select("onSelect"))
)
to the right of that there is a kendo grid. and above the tree there is a (kendo) dropdown list to select a user.
this is the controller method called by the tree:
public JsonResult WorkedHours(uint? id)
{
DocObjectArray docObjects = null;
if (id == null)
{
// get root elements
var loggedInUserRef = OmanagerUtils.GetInstance().LoggedInUser;
if (loggedInUserRef != null && loggedInUserRef.GetObject() != null && loggedInUserRef.GetObject().SubObjects != null)
{
for (int i = 0; i < loggedInUserRef.GetObject().SubObjects.GetLength(); i++)
{
var item = loggedInUserRef.GetObject().SubObjects.GetAt(i);
if (item.ToString() == TaskManagerConstants.UserWorkHours)
{
docObjects = item.TreeSubObjects;
break;
}
}
}
}
else
{
// get sub objects of a root object
var rootObj = new DocObjectRef((int)id);
docObjects = rootObj.GetObject().TreeSubObjects;
}
var returnDocObjects = new List<OmanagerItem>();
for (int i = 0; i < docObjects.GetLength(); i++)
{
var item = docObjects.GetAt(i);
var hasChildren = true;
if (item.TreeSubObjects == null)
{
hasChildren = false;
}
else
{
if (item.TreeSubObjects.GetLength() == 0)
{
hasChildren = false;
}
}
var listItem = new OmanagerItem
{
hasChildren = hasChildren,
id = item.GetOID(),
Name = item.ToString()
};
returnDocObjects.Add(listItem);
}
return Json(returnDocObjects, JsonRequestBehavior.AllowGet);
}
now, the problem is that i have to be able to select a user from the dropdown list and refresh the tree with this new data.
$("#employee").kendoDropDownList({
change: function () {
var postdata = {
id:$("#employee").val()
}
$.ajax({
url: "TaskManager/WorkedHours",
cache: false,
type: "POST",
data: postdata,
success: function (data) {
$("#treeview").data("kendoTreeView").setDataSource(data);
},
});
}
});
the problem is what do i do with this data? because my attempt did not really work.
many thanks.
You can use OutputCache attribute on WorkedHours action:
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public JsonResult WorkedHours(uint? id)
{
// rest of method
}
It helped in my case :)
Maybe this little snippet is of any help to you.
Similar to your code in the change event of my dropdown I'm calling a function that will change the request data of my TreeView DataSource.
After changing it, it calls the read() handler of the datasource so it re-reads the data:
function loadTreeViewData() {
var employee = $('#employee').getKendoDropDownList().dataItem();
WorkedHoursDataSource.transport.options.read.data = {Employee_Id:employee.id};
WorkedHoursDataSource.read();
}