Related
I have a list of maps, and i want to sort it based on values that are in another list, here is the data list:
final data = [{
'id' : 1,
},
{
'id' : 10,
},
{
'id' : 2,
},
{
'id' : 1,
},
{
'id' : 10,
},
{
'id' : 1000,
}];
And this is the sorting list:
List<int> sortingList = [1000,1, 6, 99];
I want to sort the data list based on the order of the ids that exists in the sortingList, meaning for example 1000 is in position one so i want the data that has id == 1000 at the beginning of the list, 1 is the second element of the sortingList so i want all the data that has id == 1 to be listed after the elements that has 1000 and so on. The elements that has id that's not in sortingList should be at the end of the list, the final result if i print the value id after sorting it should be like this:
for (var i = 0; i < data.length; i++) {
print(data[i]["id"]);
}
1000
1
1
10
2
10
Could you check if it is something like this you want?
void main() {
final data = [
{'id': 1},
{'id': 10},
{'id': 2},
{'id': 1},
{'id': 10},
{'id': 1000}
];
final sortingList = [1000, 1, 6, 99];
final sortingMap = {
for (var i = 0; i < sortingList.length; i++) sortingList[i]: i
};
data.sort((a, b) {
final aPos = sortingMap[a['id']!];
final bPos = sortingMap[b['id']!];
if (aPos != null && bPos != null) {
return aPos.compareTo(bPos);
} else if (aPos != null && bPos == null) {
return -1;
} else if (aPos == null && bPos != null) {
return 1;
} else {
return 0;
}
});
data.forEach((element) => print(element['id']));
// 1000
// 1
// 1
// 10
// 2
// 10
}
My array data:
data = [
{ field: { name:"name1", title:"title1" } },
{ field: { name:"name2", title:"title2" } },
{ field: { name:"name3", title:"title3" } }
];
I want to write name fields like this:
Expected Output
name1.name2.name3
I need join these object's specified field values but I don't know how to get them like this.
What I tried and failed =>
data | selectattr("field") | selectattr("name") | join(".") }}
selectattr-filter only filter data elements. Therefore, when you apply selectattr('name'), nunjucks try to filter data by elements having name-field (none of them) and returns the empty result.
The simplest way to achive name1.name2.name3 is to use a custom filter
const nunjucks = require('nunjucks');
const env = nunjucks.configure();
env.addFilter('map', function (arr, prop, ...etc) {
const f = typeof prop == 'function' ?
prop : typeof env.filters[prop] == 'function' ?
env.filters[prop] : (e) => e[prop];
return arr instanceof Array && arr.map(e => f(e, ...etc)) || arr;
});
const data = [
{field: {name: "name1", title: "title1"}},
{field: {name: "name2", title: "title2"}},
{field: {name: "name3", title: "title3"}}
];
const html = env.renderString(`{{ data | map('field') | map('name') | join('.') }}`, {data});
console.log(html);
I try to get a relational table by QueryBuilder, it works fine til I try to use skip/offset and take/limit. I expect such return:
[
{
"id": 1, // order.id
"locations": [ ... ] array of locations with same order.id
},
{
"id": 2,
"locations": [ ... ]
},
{
"id": 3,
"locations": [ ... ]
}
]
order.entity.ts
#PrimaryGeneratedColumn({ name: 'id' })
public id!: number;
#OneToMany((type) => Location, (location) => location.order, {
onDelete: 'NO ACTION',
onUpdate: 'NO ACTION',
})
public locations: Location[];
locations.entity.ts
#PrimaryGeneratedColumn({ name: 'id' })
public id!: number;
#ManyToOne((type) => Order, (order) => order.locations, {
nullable: false,
onDelete: 'NO ACTION',
onUpdate: 'NO ACTION',
})
#JoinColumn({ name: 'order_id' })
public order: Order = null;
[Query A] I get the desired output with following code: (but without using skip/take, the output is at top of this question)
const orders = getRepository(Order)
.createQueryBuilder('order')
.where('order.customer_id = :customer', { customer: user.id })
.leftJoinAndSelect('order.locations', 'location', 'location.order_id = order.order_id')
.getMany(); // output count is 35, output count with limit/take of 10 would be 10
[Query B] If I add skip/offset and take/limit, it would look like this:
const orders = getRepository(Order)
.createQueryBuilder('order')
.where('order.customer_id = :customer', { customer: user.id })
.leftJoinAndSelect('order.locations', 'location', 'location.order_id = order.order_id')
.skip(0)
.limit(10)
.getMany(); // output count is 5
But here, the output is correct but the length/count is totally wrong. Query A finds 35 orders with always 2 locations. If I remove leftJoinAndSelect from Query A and add skip and take, then it will find 35 orders as well. But Query B, with a limit/take of 10, gives me a output count of 5. It halfs the output! If limit/take is equal 8, the output is a length of 4. It halfs the output! Obviously, getMany does some magic, so I found getRawMany, what doubles the output. Because to each order, there are 2 locations. That's also not what I need. And the structure of this output is also wrong (as you can see below). getManyRaw is okay, but not if I use it with skip/take, because the output would be obviously wrong, because I need all locations to each order. Group By doesn't help here, because then I would have only 1 location by each order.
The output of getRawMany is like
[
{
"order_id": 1,
"locations_id": 100
},
{
"order_id": 1,
"locations_id": 101
},
{
"id": 2,
"locations_id": 102
},
{
"id": 2,
"locations_id": 103
},
{
"id": 3,
"locations_id": 104
},
{
"id": 3,
"locations_id": 105
}
]
As I said, using skip/take here, would give me a wrong result. How can I reach my expected output?
I hope I got your question, basically what you want to achieve is skip and take parent orders regardless of how many child locations it has. Is this correct?
If my understanding is correct, you may use such approach:
const orders = getRepository(Order) // use await if it inside async function
.createQueryBuilder('order')
.addSelect('#row_number := ' +
'CASE WHEN #parent_id <> location.order_id ' +
'THEN #row_number + 1 ' +
'ELSE #row_number END AS rn, ' +
'#parent_id := location.order_id'
)
.where('order.customer_id = :customer', { customer: user.id })
.leftJoinAndSelect('order.locations', 'location', 'location.order_id = order.order_id')
.innerJoin('(SELECT #row_number := 0)', 'init_row', '1 = 1')
.innerJoin('(SELECT #parent_id := 0)', 'init_id', '1 = 1')
.orderBy('location.order_id')
.having('rn <= 10')
.getMany(); // now output should be 10 in case u want to skip use rn > 10 AND rn <= 20 condition
I am following instructions on importing existing db to my App
(for IOS):https://www.npmjs.com/package/react-native-sqlite
Have created www folder in myProject directory, put there myDataBase.
Added folder to xcode.
this is my src code to open it and make a query :
import SQLite from 'react-native-sqlite-storage'
function errorCB(err) {
console.log("SQL Error: " + err);
}
function successCB() {
console.log("SQL executed fine");
}
function openCB() {
console.log("Database OPENED");
}
console.log('database.js')
var db = null;
export function openDB() {
// var db = SQLite.openDatabase("test.db", "1.0", "Test Database", 200000, openCB, errorCB);
db = SQLite.openDatabase({name : "words", createFromLocation : 1}, openCB,errorCB);
}
export function getWord(str) {
db.transaction((tx) => {
tx.executeSql("SELECT * FROM words", [], (tx, results) => {
console.log("Query completed");
// Get rows with Web SQL Database spec compliance.
var len = results.rows.length;
console.log('len' + len)
for (let i = 0; i < len; i++) {
let row = results.rows.item(i);
console.log(`word: ${row.str}, Dept Name: ${row.smth}`);
}
// Alternatively, you can use the non-standard raw method.
/*
let rows = results.rows.raw(); // shallow copy of rows Array
rows.map(row => console.log(`Employee name: ${row.name}, Dept Name: ${row.deptName}`));
*/
});
});
}
I am getting:
Built path to pre-populated DB asset from app bundle www subdirectory: /Users/mac/Library/Developer/CoreSimulator/Devices/06420F74-0E1C-47C1-BCAC-5D3574577349/data/Containers/Bundle/Application/75EE8E9A-276F-402F-982A-DBF30DE80802/MyApp.app/www/words
RCTLog.js:48 target database location: nosync
RCTLog.js:48 Opening db in mode READ_WRITE, full path: /Users/mac/Library/Developer/CoreSimulator/Devices/06420F74-0E1C-47C1-BCAC-5D3574577349/data/Containers/Data/Application/67D2451F-3D72-4B82-AC90-AD6DB9A82566/Library/LocalDatabase/words
Database opened
RCTLog.js:48 Good news: SQLite is thread safe!
dataBase.js:13 Database OPENED
RCTLog.js:48 open cb finished ok
sqlite.core.js:475 Error handler not provided: {message: "no such table: words", code: 5}
sqlite.core.js:572 warning - exception while invoking a callback: {"code":5}
Don't know what is the reason of this error?
I have checked in DB browser for SQLite that DB is correct and table 'words' exists in it and have rows in it.
I have tried different names for db file: 'words', 'words.db', 'words.sqlite' nothing helps.
I am running my app from console as :
react-native run-ios
SQLite.openDatabase({name:"testDB.sqlite3", createFromLocation:1,location:'Library'})
This solved my problem. testDB.sqlite3 file size is 24 MB.
testDB.sqlite and testDB.db not working, but testDB.sqlite3 is working.
Here I build a Repository, hop it help you
import BaseModule from '../baseModule';
import * as SQLite from 'expo-sqlite';
import * as MediaLibrary from 'expo-media-library';
import * as FileSystem from 'expo-file-system';
import * as Permissions from 'expo-permissions';
import DetaliItemsSettings from '../detaliItemSettings';
import ChapterSettings from '../chapterSettings';
import httpClient from '../http';
export type NovelReaderSettingsType = (items: BaseModule) => void;
export type Find = (foundItems: BaseModule[]) => void;
export default class Repository {
static dbIni: Boolean;
databaseName: string;
constructor() {
this.databaseName = 'test.db';
}
importSettings = async (uri: string) => {
try {
const {status} = await Permissions.askAsync(Permissions.MEDIA_LIBRARY);
if (status === 'granted') {
var json = await FileSystem.readAsStringAsync(uri, {encoding: 'utf8'});
if (json) console.log(json);
var item = JSON.parse(json) as {
applicationSettings: any;
items: DetaliItemsSettings[];
};
var appSettings = await this.where('ApplicationSettings');
if (item.applicationSettings) {
item.applicationSettings = httpClient.cloneItem(
appSettings.length > 0 ? appSettings[0] : {},
item.applicationSettings,
['id', 'tableName'],
);
await this.save(
item.applicationSettings,
undefined,
'ApplicationSettings',
);
}
if (item.items && item.items.length > 0) {
for (var i = 0; i < item.items.length; i++) {
var a = item.items[i];
var b = (await this.where('DetaliItems', {
novel: a.novel,
})) as DetaliItemsSettings[];
var aChapterSettings =
a.chapterSettings ?? ([] as ChapterSettings[]);
var bChaptersSettings =
b && b.length > 0
? ((await this.where('Chapters', {
detaliItem_Id: b[0].id,
})) as ChapterSettings[])
: ([] as ChapterSettings[]);
var updatedChapterSettings = [] as ChapterSettings[];
if (b && b.length > 0) {
if (a.chapterIndex) b[0].chapterIndex = a.chapterIndex;
b[0].isFavorit = true;
a = b[0];
}
aChapterSettings.forEach((x) => {
var bCh = bChaptersSettings.find(
(a) => a.chapterUrl === x.chapterUrl,
);
if (bCh)
updatedChapterSettings.push(
httpClient.cloneItem(bCh, x, ['id', 'tableName']),
);
else updatedChapterSettings.push(x);
});
let detaliItemSettings = await this.save(
a,
undefined,
'DetaliItems',
);
for (var y = 0; y <= aChapterSettings.length - 1; y++) {
let m = aChapterSettings[y];
m.detaliItem_Id = detaliItemSettings.id;
await this.save(m, undefined, 'Chapters');
}
}
}
return true;
}
} catch (error) {
console.log(error);
}
return false;
};
exportFileToDownloadFolder = async () => {
try {
const {status} = await Permissions.askAsync(Permissions.MEDIA_LIBRARY);
if (status === 'granted') {
var favoriteData = (await this.where('DetaliItems', {
isFavorit: true,
})) as DetaliItemsSettings[];
for (var i = 0; i < favoriteData.length; i++) {
var item = favoriteData[i];
item.chapterSettings = (await this.where('Chapters', {
detaliItem_Id: item.id,
})) as ChapterSettings[];
item.id = 0;
item.chapterSettings.forEach((x) => {
x.id = 0;
x.detaliItem_Id = 0;
});
}
var result = {
applicationSettings:
(await this.where('ApplicationSettings')).length > 0
? (await this.where('ApplicationSettings'))[0]
: undefined,
items: favoriteData,
};
let fileUri = FileSystem.documentDirectory + 'NovelManager.db';
await FileSystem.writeAsStringAsync(fileUri, JSON.stringify(result), {
encoding: FileSystem.EncodingType.UTF8,
});
const asset = await MediaLibrary.createAssetAsync(fileUri);
await MediaLibrary.createAlbumAsync('Download', asset, false);
return true;
}
} catch (error) {
console.log(error);
}
return false;
};
dataBasePath = () => {
return FileSystem.documentDirectory + this.databaseName;
};
createConnection = () => {
return SQLite.openDatabase(this.databaseName);
};
allowedKeys = (tableName: string) => {
return new Promise((resolve, reject) => {
this.createConnection().transaction(
(x) =>
x.executeSql(
`PRAGMA table_info(${tableName})`,
undefined,
(trans, data) => {
var keys = [] as string[];
for (var i = 0; i < data.rows.length; i++) {
if (data.rows.item(i).name != 'id')
keys.push(data.rows.item(i).name);
}
resolve(keys);
},
),
(error) => {
reject(error);
},
);
}) as Promise<string[]>;
};
selectLastRecord = async (item: BaseModule) => {
console.log('Executing SelectLastRecord...');
return (
await this.find(
item.id <= 0
? `SELECT * FROM ${item.tableName} ORDER BY id DESC LIMIT 1;`
: `SELECT * FROM ${item.tableName} WHERE id=?;`,
item.id > 0 ? [item.id] : undefined,
)
).map((x) => {
x.tableName = item.tableName;
return x;
});
};
delete = async (item: BaseModule, tableName?: string) => {
tableName = item.tableName ?? tableName;
var q = `DELETE FROM ${tableName} WHERE id=?`;
await this.execute(q, [item.id]);
};
public save = (
item: BaseModule,
insertOnly?: Boolean,
tableName?: string,
) => {
if (!item.tableName) item.tableName = tableName ?? '';
return new Promise(async (resolve, reject) => {
try {
await this.setUpDataBase();
console.log('Executing Save...');
var items = await this.where(item.tableName, {id: item.id});
var keys = (await this.allowedKeys(item.tableName)).filter((x) =>
Object.keys(item).includes(x),
);
let query = '';
let args = [] as any[];
if (items.length > 0) {
if (insertOnly) return;
query = `UPDATE ${item.tableName} SET `;
keys.forEach((k, i) => {
query += ` ${k}=? ` + (i < keys.length - 1 ? ',' : '');
});
query += ' WHERE id=?';
} else {
query = `INSERT INTO ${item.tableName} (`;
keys.forEach((k, i) => {
query += k + (i < keys.length - 1 ? ',' : '');
});
query += ') values(';
keys.forEach((k, i) => {
query += '?' + (i < keys.length - 1 ? ',' : '');
});
query += ')';
}
keys.forEach((k: string, i) => {
args.push(item[k] ?? null);
});
if (items.length > 0) args.push(item.id);
await this.execute(query, args);
resolve((await this.selectLastRecord(item))[0]);
} catch (error) {
console.log(error);
reject(error);
}
}) as Promise<BaseModule>;
};
public find = (query: string, args?: any[]) => {
return new Promise((resolve, reject) => {
this.createConnection().transaction(
async (x) => {
await this.setUpDataBase();
console.log('Executing Find..');
x.executeSql(
query,
args,
async (trans, data) => {
console.log('query executed:' + query);
var items = [] as BaseModule[];
for (var i = 0; i < data.rows.length; i++) {
var t = data.rows.item(i);
items.push(t);
}
resolve(items);
},
(_ts, error) => {
console.log('Could not execute query:' + query);
console.log(error);
reject(error);
return false;
},
);
},
(error) => {
console.log(error);
reject(error);
},
);
}) as Promise<BaseModule[]>;
};
where = async (tableName: string, query?: any) => {
var q = `SELECT * FROM ${tableName} ${query ? 'WHERE ' : ''}`;
var values = [] as any[];
if (query) {
Object.keys(query).forEach((x, i) => {
q += x + '=? ' + (i < Object.keys(query).length - 1 ? 'AND ' : '');
values.push(query[x]);
});
}
return (await this.find(q, values)).map((x) => {
x.tableName = tableName;
return x;
});
};
findOne = async (tableName: string, query?: any) => {
var items = await this.where(tableName, query);
return items && items.length > 0 ? items[0] : undefined;
};
execute = async (query: string, args?: any[]) => {
return new Promise((resolve, reject) => {
this.createConnection().transaction(
(tx) => {
console.log('Execute Query:' + query);
tx.executeSql(
query,
args,
(tx, results) => {
console.log('Statment has been executed....' + query);
resolve(true);
},
(_ts, error) => {
console.log('Could not execute query');
console.log(args);
console.log(error);
reject(error);
return false;
},
);
},
(error) => {
console.log('db executing statement, has been termineted');
console.log(args);
console.log(error);
reject(error);
throw 'db executing statement, has been termineted';
},
);
});
};
public dropTables = async () => {
await this.execute(`DROP TABLE if exists ApplicationSettings`);
await this.execute(`DROP TABLE if exists DetaliItems`);
await this.execute(`DROP TABLE if exists Chapters`);
Repository.dbIni = false;
await this.setUpDataBase();
};
setUpDataBase = async () => {
let applicationSetupQuery = `CREATE TABLE if not exists ApplicationSettings (
id INTEGER NOT NULL UNIQUE,
backGroundColor TEXT NOT NULL,
fontSize INTEGER NOT NULL,
lineHeight INTEGER NOT NULL,
fontFamily TEXT NOT NULL,
marginLeft INTEGER NOT NULL,
marginRight INTEGER NOT NULL,
detaliItem_Id INTEGER,
selectedParserIndex INTEGER,
PRIMARY KEY(id AUTOINCREMENT)
);`;
let detaliItemsQuery = `CREATE TABLE if not exists DetaliItems (
image TEXT NOT NULL,
title TEXT NOT NULL,
description TEXT NOT NULL,
novel TEXT NOT NULL,
parserName TEXT NOT NULL,
chapterIndex INTEGER NOT NULL,
id INTEGER NOT NULL,
isFavorit INTEGER NOT NULL,
PRIMARY KEY(id AUTOINCREMENT)
);`;
let chapterQuery = `CREATE TABLE if not exists Chapters (
id INTEGER NOT NULL UNIQUE,
chapterUrl TEXT NOT NULL,
isViewed INTEGER NOT NULL,
currentProgress NUMERIC NOT NULL,
finished INTEGER NOT NULL,
detaliItem_Id INTEGER NOT NULL,
PRIMARY KEY(id AUTOINCREMENT),
CONSTRAINT "fk_detaliItem_id" FOREIGN KEY(detaliItem_Id) REFERENCES DetaliItems(id)
);`;
if (!Repository.dbIni) {
console.log('dbIni= false, setUpDataBase');
await this.execute(applicationSetupQuery);
await this.execute(detaliItemsQuery);
await this.execute(chapterQuery);
Repository.dbIni = true;
} else {
console.log('dbIni= true, setUpDataBase');
}
};
}
I'm struggling with passing the csv strings via ViewBag in the correct format.
I know the result should be like ["Blue","Brown","Green"] but my script is generated as [Blue,Brown,Green] instead.
And then I get the Uncaught ReferenceError : Blue is not defined.
How can I format it in my controller to pass in the correct way?
This is my code in the controller
public ActionResult Index()
{
List<string> teamsList = new List<string>();
List<string> salesCount = new List<string>();
foreach (var team in Db.Teams)
{
teamsList.Add(team.Name);
int count = Db.LeadCampaigns.Count(i => Db.Agents.FirstOrDefault(a => a.AgentId == i.AgentId).TeamId == team.TeamId && i.LeadStatusId == Db.LeadStatuses.FirstOrDefault(s => s.Name == "SALE").LeadStatusId);
salesCount.Add(count.ToString());
}
ViewBag.SaleCount_List = string.Join(",", salesCount);
ViewBag.TeamName_List = string.Join(",", teamsList);
return View();
}
And here is my script in the view.
<script>
var barChartData =
{
labels: [#Html.Raw(ViewBag.TeamName_List)],
datasets: [{
label: 'TeamWise Sales Count',
backgroundColor: [
"#f990a7",
"#aad2ed",
"#9966FF",
"#99e5e5",
"#f7bd83",
],
borderWidth: 2,
data: [#ViewBag.SaleCount_List]
}]
};
window.onload = function () {
var ctx1 = document.getElementById("barcanvas").getContext("2d");
window.myBar = new Chart(ctx1,
{
type: 'bar',
data: barChartData,
options:
{
title:
{
display: true,
text: "TeamWise Sales Count"
},
responsive: true,
maintainAspectRatio: true
}
});
}
Your plugin expects an array of values, but your passing it a string by using String.Join().
Pass the array using
ViewBag.SaleCount_List = salesCount;
ViewBag.TeamName_List = teamsList;
(or better pass a view model with 2 IEnumerable<string> properties) and then convert it to a jacascript array
var saleCounts = #Html.Raw(Json.Encode(ViewBag.SaleCount_List))
var teamNames = #Html.Raw(Json.Encode(ViewBag.TeamName_List))
var barChartData =
{
labels: teamNames,
datasets: [{
....
],
borderWidth: 2,
data: saleCounts
}]
};
Using your current syntax:
const string quote = "\"";
foreach (var team in Db.Teams)
{
teamsList.Add(quote + team.Name + quote);
int count = Db.LeadCampaigns.Count(i => Db.Agents.FirstOrDefault(a => a.AgentId == i.AgentId).TeamId == team.TeamId && i.LeadStatusId == Db.LeadStatuses.FirstOrDefault(s => s.Name == "SALE").LeadStatusId);
salesCount.Add(count.ToString());
}