How to use insert() in sequelize migration? - javascript

I want to create only one row using insert() in Sequelize migration. I have seen the examples for bulkInsert() but don't want to use bulk.
We have this function to create only one row:
insert(instance, tableName, values, options)
But I don't understand what's the instance here in param?
I am using bulkInsert because it does not ask for instance param.
It will be great if you can add insert in my code written below.
Migration lib: https://github.com/sequelize/sequelize/blob/master/lib/query-interface.js
//Code for insertion using bulkInsert
module.exports = {
up: queryInterface => {
queryInterface.describeTable("Platforms").then(attributes => {
return queryInterface.bulkInsert("Platforms", [
{
id: 6,
display_name: "Booking.com",
code: "booking.com"
}
]);
});
},
down: queryInterface => {
return queryInterface.bulkDelete("Platforms", {
id: 6
});
}
};

import Platform from '../models/Platform';
module.exports = {
up: queryInterface => {
queryInterface.describeTable("Platforms").then(attributes => {
return queryInterface.insert(Platform, "Platforms", [
{
id: 6,
display_name: "Booking.com",
code: "booking.com"
}
]);
});
},
down: queryInterface => {
return queryInterface.bulkDelete("Platforms", {
id: 6
});
}
};
Instance here is for model instance that you define using sequilize.

Related

Jest - Object is being re-used across tests

I have a simple function to test. I am using jest, and I am assigning in every it("") statement, an assertion constant, with my ArrayOfObjects.
While the first test passes. All other tests fail, cause they are using the object(assertion) from the first test.
How can I teardown the constant value in every test? Or in general fix it? Here is the code:
describe('Fn: CreateEdges', () => {
it('should RETURN [1 Key]', () => {
const assertion = [
{
identifier: {
name: '1'
}
}
];
const expectation = [
{
key: '1'
}
];
expect(createFn(assertion)).toEqual(expectation);
});
it('should RETURN [2 Keys]', () => {
const assertion = [
{
identifier: {
name: '1',
},
identifier: {
name: '2'
}
}
];
const expectation = [
{
key: '1',
},
{
key: '2',
}
];
expect(createFn(assertion)).toEqual(expectation); // This fails cause it is using the Object from test1
});
});
The createFn below:
import * as R from 'ramda';
function createnFn(array: any[]) {
return R.flatten(
array.map(({ identifier }: any) =>
identifier.key.map((marker: { name: string }) => ({
source: identifier.name,
target: marker.name,
}))
)
);
}
export default R.memoizeWith(R.identity, createFn);
As it was already mentioned, memoization causes the problem, it makes the function stateful. Non-memoized createnFn is local to the module, only memoized version of it is exported. Since it's reused between multiple tests, this results in test cross-contamination.
The solution is to re-import the module. It should be imported in tests not on top level but in tests, re-import is done with jest.isolateModules or jest.resetModules:
beforeEach(() => {
jest.resetModules();
})
it('should RETURN [1 Key]', () => {
const createFn = require('...').default;
...
expect(createFn(assertion)).toEqual(expectation);
});
Ciao, you problem could be related to function memoization.
Basically, Memoization is a technique that stores values in cache to improve performances. Try to remove R.memoizeWith(R.identity, createFn) and problem should disappears.

Create new object from array

I'm trying to create new object with different properties name from Array.
Array is:
profiles: Array(1)
0:
column:
name: "profileName"
title: "Profile name"
status: "Active"
I want to create new function that return object with two properties:
id: 'profileName',
profileStatus: 'Active'
The function that I have create is returning only one property as undefined undefined=undefined.
function getProfile(profiles) {
if (!profiles.length) return undefined;
return profiles.reduce((obj, profile) => {
console.log('profiles', profile);
return ({
...obj,
id: profile.column.name,
profileStatus: profile.status,
});
}, {});
}
The function getProfile is taking as input array 'profiles' from outside,
I've just tested here and this seems to be working actually
const getProfile1 = (p) => p.reduce((obj, profile) =>({
...obj,
id: profile.column.name,
profileStatus: profile.status,
}), {});
You can use map as an alternative.
var profiles = [{"column":{"name": "profileName3","title": "3Profile name"},"status": "Active"},{"column":{"name": "profileName","title": "Profile name"},"status": "Active"}];
function getProfile(profiles) {
if (!profiles.length) return undefined;
return profiles.map(function(profile,v){
return {id:profile.column.name,profileStatus: profile.status};
});
}
console.log(getProfile(profiles));
Whenever I use reduce in this way, I usually index the final object by some sort of an id. As noted in another answer, you could use map in this situation as well. If you really want your final data structure to be an object, however, you could do something like this:
/**
* returns object indexed by profile id
*/
const formatProfiles = (profiles) => {
return profiles.reduce((obj, profile) => {
return {
...obj,
[profile.id]: {
id: profile.column.name,
profileStatus: profile.status,
}
};
}, {});
};
const profiles = [
{
id: 0,
status: 'active',
column: {
name: "profile_name_1",
title: "profile_title_1",
},
},
{
id: 1,
status: 'inactive',
column: {
name: "profile_name_2",
title: "profile_title_2",
}
}
];
const result = formatProfiles(profiles);
/**
* Result would look like this:
*/
// {
// '0': { id: 'profile_name_1', profileStatus: 'active' },
// '1': { id: 'profile_name_2', profileStatus: 'inactive' }
// }

#Ngrx/store: how to query models with relationships

I an Angular 2 app using Redux (with #ngrx/store), I have modeled the store this way:
{
modelA: {
ids: [1, 2],
entities: { 1: { name: "name modelA 1" },
2: { name: "name modelA 2" }
}
},
modelB: {
ids: [5, 8],
entities: { 5: { name: "name modelB 5" },
8: { name: "name modelA 8" },
9: { name: "name modelA 9" }
}
}
}
Basically, I have 2 types of objects: modelA and modelB. This is ok for now.
But I can't find which is the best way to write a relationship between then, representing something like modelA has many modelB (one-to-many). Can I do something like this?
modelAmodelB: {
entities: {
1: [5],
2: [8, 9]
}
}
This is in the root of the store, it's not a child from 'modelA'.
This might work, but how then would I 'query' the modelB from a specific modelA, using #ngrx/store methods? Because if I write a selector function that reads the global state and returns the partial state from modelAmodelB, I don't have access to the rest of the state when I compose my functions. Example:
compose(getModelAEntities(number[]), getModelAModelBRelations(modelA_id: number), getModelAModelBState() );
I can query this using Observable.combineLast
Observable
.combineLatest(
this.store.select('contentContents'),
this.store.select('contents'),
(relations: any, contents: any) => {
return relations.entities[1].map( id => {
return contents.entities[id]
})
}
).subscribe( data => {
console.log(data);
})
But I don't know if this is right: anytime I change modelA entities object (adding a new one, for example), the subscribe() is called, but the output is the same, because neither modelA entity has changed nor its modelB related objects.
PS: I could do the query this way
export const getModelAModelBs = (id) => {
return state =>
state.select( (s: any) => [s.modelAModelB.entities[id], s.modelB.entities])
.distinctUntilChanged( (prev, next) => {
const new_m = (next[0] || []).map( id => {
return next[1][id];
});
const old_m = (next[0] || []).map( id => {
return prev[1][id];
});
return prev[0] === next[0] && (JSON.stringify(new_m) === JSON.stringify(old_m))
})
.map( ([ids = [], modelBs]) => ids.map( id => modelBs[id]) );
};
//use the selector
this.store.let(getModelAModelBs(1)).subscribe( data => {
console.log(data)
})
But I don't know if this is the best approach.
I was struggling with the same issue and came up with a solution of wrappers.
Please take a look at the ngrx-entity-relationship library: https://www.npmjs.com/package/ngrx-entity-relationship
you can create selectors like that:
export const selectUserWithCompany = entityUser(
entityUserCompany(),
);
and then to use it with the store
this.store.select(selectUserWithCompany, 'userId');
to get
{
id: 'userId',
companyId: 'companyId',
company: {
id: 'companyId',
// ...,
},
// ...,
}

normalizr v3 and JSON api

I want to normalise the responses I receive from an API. A typical response could look something like this:
// Get all projects
{data:[
{
id: 1
...
team:{
data: {
id:15
...
}
}
},
{
id:2,
....
},
{
id:3,
...
}
]}
How do I write my schemas so that it removes the 'data' container?
Currently, my schema looks like:
export const project = new schema.Entity('projects', {
team: team, // team omitted
},
{
processStrategy: (value, parent, key) => parent.data
}
)
export const arrayOfProjects = new schema.Array(project)
And I am using it like:
const normalizedProjects = normalize(jsonResponse, arrayOfProjects)
normalizedProjects then looks like this:
{
entities:{
projects:{
undefined:{
0:{
team:{
data:{
id:15,
...
}
}
},
1:{...},
2:{...}.
...
50:{...},
}
}
},
result:[] // length is 0
}
I'm not sure why the list of projects is contained in 'undefined', either?
I also use json_api schema.
How about like this?
const projectsSchema = new schema.Entity('projects', {}, {
processStrategy: processStrategy
});
export const processStrategy = (value, parent, key) => {
const attr = value.attributes;
delete value.attributes;
return { ...value, ...attr };
};
export const fetchProjectsSchema = {
data: [projectsSchema]
}
Each of your entity schema that you want to have the data omitted (or anything else fundamentalyl changed) needs to include a processStrategy that you write to remove or change any data. (see more examples in the tests)

How to create an observable stream of custom objects using RxJS operators

I currently have input which looks as follows
const config = {
'mainA': { sub1: { name: 'test1'}, sub2: { name: 'test2'}},
'mainB': { sub1: { name: 'test3'}, sub2: { name: 'test4'}}
};
I'm trying to write a function (createCustomObservable) which would create an observable using standard RsJS operators as follows
var observable = createCustomObservable(config);
observable.subscribe((x) => console.log(x));
The console output should read as follows
{'mainA': 'test1'} -> {'mainA': 'test2'} -> {'mainB': 'test3'} -> {'mainB': 'test4'}
A series of objects with a single propery
Does anyone have any idea how to realise this using RxJS operators? Any help would be appreciated.
The main problem for what you trying to solve is traverse the object to get all the objects that contains the "name" field, and get their value.
There's no Rx operator to automatically do that, so to achieve this task you can simply use Rx.Observable.create - https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/create.md
const config = {
'mainA': {
sub1: {
name: 'test1'
},
sub2: {
name: 'test2'
}
},
'mainB': {
sub1: {
name: 'test3'
},
sub2: {
name: 'test4'
}
}
};
function traverse(o, func) {
for (var i in o) {
func.apply(this, [i, o[i]]);
if (o[i] !== null && typeof(o[i]) == "object") {
//going on step down in the object tree!!
traverse(o[i], func);
}
}
}
var source = Rx.Observable.create(function(observer) {
traverse(config, function(key, value) {
if (key == "name")
observer.onNext(value);
});
observer.onCompleted();
return function() {
console.log('disposed');
};
});
source.subscribe(function(next) {
console.log(next);
})
Sample: https://jsbin.com/yolufovubi/edit?js,console
we can create a new stream by Observable constructor, You have to manually call next(), error() and complete() functions.
function createCustomObservable(config) {
return new Observable(
observer => {
try {
observer.next(config)
} catch(err) {
observer.error(err);
} finally {
observer.complete();
}
})
}
and use it this way
var observable = createCustomObservable(config);
observable.subscribe((x) => console.log(x));

Categories

Resources