I am using promise with knexjs, but why promise join is not run in sequence, rows got deleted after inserted:
exports.seed = function(knex, Promise) {
return Promise.join(
knex('states').del(),
knex('states').insert([
{
'id': 1,
'name': 'Georgia'
},
{
'id': 2,
'name': 'Tennessee'
}
]);
);
};
Join is for promises that run in parallel, not in sequence. "For coordinating multiple concurrent discrete promises." Since you want to delete before insert they are not concurrent.
Promises are executed as soon as they are created so I think this is a case for a regular then:
exports.seed = function(knex, Promise) {
return knex('states').del()
.then(function() {
return knex('states').insert([
{
'id': 1,
'name': 'Georgia'
},
{
'id': 2,
'name': 'Tennessee'
}
]);
);
};
Of if you like ES6 and having things line up:
exports.seed = (knex) => {
return B.resolve()
.then(() => knex('states').del())
.then(() => knex('states').insert([
{
'id': 1,
'name': 'Georgia'
},
{
'id': 2,
'name': 'Tennessee'
}
]));
}
Related
I am new to python and am struggling with remove a key and value from a json return by an http request. When querying a task I get the following back.
data = requests.get(url,headers=hed).json()['data']
[{
'gid': '12011553977',
'due_on': None,
'name': 'do something',
'notes': 'blalbla,
'projects': [{
'gid': '120067502445',
'name': 'Project1'
}]
}, {
'gid': '12002408815',
'due_on': '2021-10-21',
'name': 'Proposal',
'notes': 'bla',
'projects': [{
'gid': '12314323523',
'name': 'Project1'
}, {
'gid': '12314323523',
'name': 'Project2'
}, {
'gid': '12314323523',
'name': 'Project3'
}]
I am trying to remove 'gid' from all projects so projects look like this
'projects': [{
'name': 'Company'
}]
What is the best way to do this with python3?
You can use recursion to make a simpler function to handle all elements and sub-elements. I haven't done extensive testing, or included any error checking or exception handling; but this should be close to what you want:
def rec_pop(top_level_list,key_to_pop='gid'):
for item in top_level_list:
item.pop(key_to_pop)
for v in item.values():
if isinstance(v,list):
rec_pop(v)
# call recursive fn
rec_pop(data)
Result:
In [25]: data
Out[25]:
[{'due_on': None,
'name': 'do something',
'notes': 'blalbla',
'projects': [{'name': 'Project1'}]},
{'due_on': '2021-10-21',
'name': 'Proposal',
'notes': 'bla',
'projects': [{'name': 'project2'}]}]
I'm trying to do unit testing on my nodejs-express method with sequelize-mock.
Controller
const getDetailsByUserId = async (id) => {
try {
const userId = id ?? 0;
const details = await Model.findAll(
{
raw: true,
where: { user_id: userId }
}
);
if (details && details .length > 0) {
return {
status: 200,
success: true,
message: 'details found.',
data: details
}
}
return {
status: 404,
success: false,
message: 'details not found',
data: []
}
} catch (error) {
return {
status: 500,
success: false,
message: error.message || "An error occurred while getting details.",
data: null
}
}
}
Test
jest.mock('../models/details', () => () => {
const SequelizeMock = require("sequelize-mock");
const dbMock = new SequelizeMock();
return dbMock.define('users', [
{
id: 1,
user_id: 123
name: 'John Doe 1'
},
{
id: 2,
user_id: 456
name: 'John Doe 2'
},
{
id: 3,
user_id: 789
name: 'John Doe 3'
}
]);
});
test('should return 404 and an empty array', async () => {
const userId = 147;
const details = await controller.getDetailsByUserId(userId);
expect(details.status).toEqual(404);
});
I always get the status of 200 instead of 404 here. I checked the returned data and it's returning the records of the defined mocked model.
Actual Result:
[
fakeModelInstance {
options: {
timestamps: true,
paranoid: undefined,
createdAt: undefined,
updatedAt: undefined,
deletedAt: undefined,
isNewRecord: true
},
_values: {
'0': [Object],
'1': [Object],
'2': [Object],
user_id: 147,
id: 1,
createdAt: 2021-09-18T00:55:25.976Z,
updatedAt: 2021-09-18T00:55:25.976Z
},
dataValues: {
'0': [Object],
'1': [Object],
'2': [Object],
user_id: 147,
id: 1,
createdAt: 2021-09-18T00:55:25.976Z,
updatedAt: 2021-09-18T00:55:25.976Z
},
hasPrimaryKeys: true,
__validationErrors: []
}
]
QUESTIONS:
Is there something I can do to get the expected result (empty array) for this scenario?
the raw: true seems to be not working when it is mocked. Is there a way could log the result on raw object?
NOTE: This only happens on the unit testing. When accessing the endpoint on postman it returns the expected result.
According to the docs, findAll() will always return an array of a single result based on the where query in the options. This is why you will never get an empty array.
See more: https://sequelize-mock.readthedocs.io/en/stable/api/model/#findalloptions-promisearrayinstance
I'm about to write an app in angular. It receives an answer from an api. Inside this answer is an array indexed with strings (index signature). How can I map this array into a regular array?
The api looks like this
{
"Information": {
"Created": "2019-04-25",
"Version": "1.2"
},
"Files": {
"2019-04-26": {
'name': 'file1',
'size': 5,
},
"2019-04-25": {
'name': 'file2',
'size': 3,
},
...
}
}
And i want to map it an object that looks like this
export class Model {
'Information': {
'Created': string,
'Version': string,
};
'Files': [{
'date': Date,
'name': string,
'size': number,
}];
}
Here I would like to map the answer
getdata(url): void {
this.http.get<>(url).subscribe(data => {
// code
}
);
}
I haven't tested any of this, but, in summary, the for loop retrives all of the keys of the object data.File and the you can access this object through that key.
getdata(url): void {
this.http.get<>(url).subscribe((response: any) => {
const model: Model = new Model();
model.Files = [];
if (response.Information) {
const information: any = response.Information;
if (information.Created && information.Version) {
model.Information = {
'Created': information.Created,
'Version': information.Version
};
}
}
for (const date in data) {
if (data.File.hasOwnProperty(date)) {
const file: any = data.File[date];
model.Files.push({
'date': date,
'name': file.name,
'size': file.size
});
}
}
});
}
Object.keys(o.Files)
.map(function(k ) {
return {date: k, name: o.Files[k].name, size: o.Files[k].size}
});
It should probably look like this:
data: Array<Data>;
getData() {
this.http.get(`url`).subscribe((data) => {
this.data = data.map(item => {
const output = {};
output.information = item.information;
output.files = Object.keys(item.files).map(key => {
return {
date: new Date(key),
name: item.files[key].name,
size: item.files[key].size
};
});
return output;
});
});
}
I need to save JSON data into a .json file after converting an object to a string using JSON.stringify
This is my current code:
const jsonObject: object = {
'countryName': 'Switzerland',
'users': [
{
'id': 1,
'name': 'Basel',
'founded': -200,
'beautiful': true,
'data': 123,
'keywords': ['Rhine', 'River']
},
{
'id': 1,
'name': 'Zurich',
'founded': 0,
'beautiful': false,
'data': 'no',
'keywords': ['Limmat', 'Lake']
}
]
};
const myData = JSON.stringify(jsonObject);
Note: I want to save this data dynamically, and I was used to jsonConverter of jsonTypescript2.
I tried using this method:-
let a = document.createElement('a');
// JSON.stringify(jsonObject), 'ex.json' // another
a.setAttribute('href', 'data:application/json;charset=UTF-8,' + encodeURIComponent(myData));
Okay after 6 days ago I discover best solution, how to connect between Angular 6 and Node.js + json File directly and dynamically .
npm install file-saver --save
import { saveAs } from 'file-saver';
const jsonObject: object = {
'City': [
{
'id': 1,
'name': 'Basel',
'founded': -200,
'beautiful': true,
'data': 123,
'keywords': ['Rhine', 'River']
},
{
'id': 1,
'name': 'Zurich',
'founded': 0,
'beautiful': false,
'data': 'no',
'keywords': ['Limmat', 'Lake']
}
]
};
const blob = new Blob([JSON.stringify(jsonObject)], {type : 'application/json'});
saveAs(blob, 'abc.json');
You can use fs.js NPM module to write data to file
There are a lot of details in the filesystem API. The most common way (as far as I know) is:
var fs = require('fs');
fs.writeFile("/fileName.json", myData, function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
var mysql = require("mysql");
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'nodejs'
});
exports.players_list = function(req, res) {
var data = {title: "", res: {}};
if (authenticate(req, res)) {
results_aaa(function(result) {
console.log(result);
res.render('players/players', {title: 'Players List', res: result});
});
} else {
req.session.error = 'Please login to continue.';
res.redirect('/login');
}
};
function results_aaa(callback) {
teams(function(res) {
callback(res)
});
}
function teams(callback) {
var query = connection.query("select * from team", function(err, result, fields) {
for (var index in result)
{
players(result[index].id, function(results) {
callback(results);
});
}
});
}
function players(id, callback) {
query("SELECT * FROM players where team = " + id, function(results) {
callback(results);
});
}
function query(sql, callback) {
connection.query(sql, function(error, results, fields) {
callback(results);
});
}
I am trying to group the data of a particular team with team players.
And i'm getting partial output. But if i use console.log(), i am able to see the entire output in console
Output in console looks like this.
Express server listening on port 8081
[ { id: 2, player_name: 'Virat Kohli', team: '1' },
{ id: 4, player_name: 'A B DeVilliers', team: '1' },
{ id: 6, player_name: 'Chris Gayle', team: '1' } ]
GET /players 200 162ms - 638
[ { id: 7, player_name: 'Ajinkya Rahane', team: '2' },
{ id: 8, player_name: 'Shane Watson', team: '2' },
{ id: 9, player_name: 'Stuart Binny', team: '2' },
{ id: 10, player_name: 'Karun Nair', team: '2' },
{ id: 11, player_name: 'Sanju Samson', team: '2' } ]
[ { id: 1, player_name: 'Virender Sehwag', team: '3' },
{ id: 3, player_name: 'David Miller', team: '3' },
{ id: 5, player_name: 'Shaun Marsh', team: '3' } ]
Only team id with 1 is appearing in jade view.
And is the procedure followed is correct. I am new to node js.
Thanks in advance:)
This is because you are sending the response after you receive the first callback, i.e., the team1 results and before you receive the other two, the 2nd and 3rd team results.
In function teams(), use
if(index == result.length-1) { callback(results); }
instead of just
callback(results);
inside the for loop.