RepositoryNotFoundError : TypeORM - javascript

I am trying to get the following example working:
https://github.com/typeorm/javascript-example/tree/master/src/app3-es6
I am running into the following error:
Error
at new RepositoryNotFoundError (...\node_modules\typeorm\connection\error\RepositoryNotFoundError.js:24:23)
at Connection.findRepositoryAggregator (...\node_modules\typeorm\connection\Connection.js:513:19)
at Connection.getRepository (...\node_modules\typeorm\connection\Connection.js:405:21)
at ...\index.js:27:37
name: 'RepositoryNotFoundError',
message: 'No repository for "Post" was found. Looks like this entity is not registered in current "default" connection?'
here is index.js
const typeorm = require("typeorm"); // import * as typeorm from "typeorm";
const Post = require("./model/Post"); // import {Post} from "./model/Post";
// import Post from './model/Post.js';
const Category = require("./model/Category"); // import {Category} from "./model/Category";
typeorm.createConnection({
driver: {
type: "oracle",
host: "localhost",
port: 1521,
username: "uname",
password: "pwd",
sid: "dev"
},
entities: [
__dirname + "/entity/*.js"
],
autoSchemaSync: true
}).then(function (connection) {
console.log(connection);
let post = new Post.Post();
post.title = "Control flow based type analysis";
post.text = "TypeScript 2.0 implements a control flow-based type analysis for local variables and parameters.";
post.categories = [new Category.Category(0, "TypeScript"), new Category.Category(0, "Programming")];
let postRepository = connection.getRepository(Post.Post);
postRepository.persist(post)
.then(function(savedPost) {
console.log("Post has been saved: ", savedPost);
console.log("Now lets load all posts: ");
return postRepository.find();
})
.then(function(allPosts) {
console.log("All posts: ", allPosts);
});
}).catch(function(error) {
console.log("Error: ", error);
});
Post.js in /model/
/*export */ class Post {
constructor(id, title, text, categories) {
this.id = id;
this.title = title;
this.text = text;
this.categories = categories;
}
}
module.exports = {
Post: Post
};
Category.js
/*export */ class Category {
constructor(id, name) {
this.id = id;
this.name = name;
}
}
module.exports = {
Category: Category
};
PostSchema.js in /entity/
const Post = require("../model/Post"); // import {Post} from "../model/Post";
const Category = require("../model/Category"); // import {Category} from "../model/Category";
const PostSchema = {
target: Post,
columns: {
id: {
primary: true,
type: "int",
generated: true
},
title: {
type: "string"
},
text: {
type: "text"
}
},
relations: {
categories: {
target: Category,
type: "many-to-many",
joinTable: true,
cascadeInsert: true
}
}
};
module.exports = {
PostSchema: PostSchema
};
CategorySchema.js
const Category = require("../model/Category"); // import {Category} from "../model/Category";
const CategorySchema = {
target: Category,
columns: {
id: {
primary: true,
type: "int",
generated: true
},
name: {
type: "string"
}
}
};
module.exports = {
CategorySchema: CategorySchema
};
i dont know what i am doing wrong

It looks like your entity import is not working. If you import via the wildcard:
entities: [
__dirname + "/entity/*.js"
],`
Make sure your model is compiled to js. You also could just import
createConnection({
...,
entities: [
Post,
...
],}).then(...)

For those who are using typescript and experience this problem: Be reminded that you need to include both ts and js file suffixes when specifying the entities-path:
ts used when locally running with ts-node
js used when having
built for production via tsc.
Code:
import * as path from 'path';
// ...
entities: [
// assuming _dirname is your project root
path.resolve(__dirname, '**/*.entity{.ts,.js}'),
],

I had the same problem for months and finally figured out what I was doing wrong.
When you import Entities, make sure the file names are EXACTLY matching. It's not going to throw any errors, but during the run time, it's going to throw the above error.
Ex. In the entity or model classes, if we import like this,
import { FooClass } from "./foo-Class.model";
it's different from
import { FooClass } from "./foo-class.model";
It won't show any errors, but when you try to call the table, it will show the exact same error.

I had the same problem. None of the solutions worked for me. After much debugging I figured out that you'll receive this error if your connection is closed.
So if you are facing this error, make sure your connection is not closed.
try {
connection = getConnection(config.name)
//after adding this if block, I no longer received this error
if (!connection.isConnected) {
await connection.connect();
}
} catch(err) {
connection = await createConnection(config);
}
If it is closed, connect it again.

Related

How to connect to Graphql server using Ember-Apollo?

I am working with a full stack GraqlQL based application. The server is working fine and now I need to try out the first queries and mutations on the client side. For some reason, the "monitoring" route, and everything that follows it, is not displayed. Below I will show the files that I have edited or created.
items.graphql:
query {
items {
_id
name
}
}
environment.js:
'use strict';
module.exports = function(environment) {
let ENV = {
apollo: {
apiURL: 'http://localhost:5000/graphql'
},
modulePrefix: 'client',
environment,
rootURL: '/',
locationType: 'auto',
EmberENV: {
FEATURES: {
//
},
EXTEND_PROTOTYPES: {
Date: false
}
},
APP: {
//
}
};
if (environment === 'development') {
//
}
if (environment === 'test') {
ENV.locationType = 'none';
ENV.APP.LOG_ACTIVE_GENERATION = false;
ENV.APP.LOG_VIEW_LOOKUPS = false;
ENV.APP.rootElement = '#ember-testing';
ENV.APP.autoboot = false;
}
if (environment === 'production') {
//
}
return ENV;
};
monitoring.js (route):
import Route from '#ember/routing/route';
import { queryManager } from 'ember-apollo-client';
import query from 'client/gql/items.graphql';
export default Route.extend({
apollo: queryManager(),
model() {
return this.apollo.watchQuery({ query }, 'items');
}
});
monitoring.hbs:
<h3>Monitoring</h3>
<div>
{{#each model as |item|}}
<h3>{{item.name}}</h3>
{{/each}}
</div>
{{outlet}}
Thank you for attention!
I see this error:
Uncaught (in promise) Error: fetch is not defined - maybe your browser targets are not covering everything you need?
The solution is to fix two things.
First is to put this in ember-cli-build.js:
'ember-fetch': {
preferNative: true
}
And fix the route file:
import Route from '#ember/routing/route';
import { queryManager } from 'ember-apollo-client';
import query from 'client/gql/queries/items.graphql';
export default Route.extend({
apollo: queryManager(),
async model() {
let queryResults = await this.apollo.watchQuery({ query }, 'items');
return Object.values(queryResults);
}
});

Subscriptions not working with Prisma 2 and Nexus?

Subscriptions with Nexus are undocumented but I searched Github and tried every example in the book. It's just not working for me.
I have cloned Prisma2 GraphQL boilerplate project & my files are as follows:
prisma/schema.prisma
datasource db {
provider = "sqlite"
url = "file:dev.db"
default = true
}
generator photon {
provider = "photonjs"
}
generator nexus_prisma {
provider = "nexus-prisma"
}
model Pokemon {
id String #default(cuid()) #id #unique
number Int #unique
name String
attacks PokemonAttack?
}
model PokemonAttack {
id Int #id
special Attack[]
}
model Attack {
id Int #id
name String
damage String
}
src/index.js
const { GraphQLServer } = require('graphql-yoga')
const { join } = require('path')
const { makeSchema, objectType, idArg, stringArg, subscriptionField } = require('#prisma/nexus')
const Photon = require('#generated/photon')
const { nexusPrismaPlugin } = require('#generated/nexus-prisma')
const photon = new Photon()
const nexusPrisma = nexusPrismaPlugin({
photon: ctx => ctx.photon,
})
const Attack = objectType({
name: "Attack",
definition(t) {
t.model.id()
t.model.name()
t.model.damage()
}
})
const PokemonAttack = objectType({
name: "PokemonAttack",
definition(t) {
t.model.id()
t.model.special()
}
})
const Pokemon = objectType({
name: "Pokemon",
definition(t) {
t.model.id()
t.model.number()
t.model.name()
t.model.attacks()
}
})
const Query = objectType({
name: 'Query',
definition(t) {
t.crud.findManyPokemon({
alias: 'pokemons'
})
t.list.field('pokemon', {
type: 'Pokemon',
args: {
name: stringArg(),
},
resolve: (parent, { name }, ctx) => {
return ctx.photon.pokemon.findMany({
where: {
name
}
})
},
})
},
})
const Mutation = objectType({
name: 'Mutation',
definition(t) {
t.crud.createOnePokemon({ alias: 'addPokemon' })
},
})
const Subscription = subscriptionField('newPokemon', {
type: 'Pokemon',
subscribe: (parent, args, ctx) => {
return ctx.photon.$subscribe.pokemon()
},
resolve: payload => payload
})
const schema = makeSchema({
types: [Query, Mutation, Subscription, Pokemon, Attack, PokemonAttack, nexusPrisma],
outputs: {
schema: join(__dirname, '/schema.graphql')
},
typegenAutoConfig: {
sources: [
{
source: '#generated/photon',
alias: 'photon',
},
],
},
})
const server = new GraphQLServer({
schema,
context: request => {
return {
...request,
photon,
}
},
})
server.start(() => console.log(`🚀 Server ready at http://localhost:4000`))
The related part is the Subscription which I don't know why it's not working or how it's supposed to work.
I searched Github for this query which results in all projects using Subscriptions.
I also found out this commit in this project to be relevant to my answer. Posting the related code here for brevity:
import { subscriptionField } from 'nexus';
import { idArg } from 'nexus/dist/core';
import { Context } from './types';
export const PollResultSubscription = subscriptionField('pollResult', {
type: 'AnswerSubscriptionPayload',
args: {
pollId: idArg(),
},
subscribe(_: any, { pollId }: { pollId: string }, context: Context) {
// Subscribe to changes on answers in the given poll
return context.prisma.$subscribe.answer({
node: { poll: { id: pollId } },
});
},
resolve(payload: any) {
return payload;
},
});
Which is similar to what I do. But they do have AnswerSubscriptionPayload & I don't get any generated type that contains Subscription in it.
How do I solve this? I think I am doing everything right but it's still not working. Every example on GitHub is similar to above & even I am doing the same thing.
Any suggestions?
Edit: Subscriptions aren't implemented yet :(
I seem to have got this working despite subscriptions not being implemented. I have a working pubsub proof of concept based off the prisma2 boilerplate and Ben Awad's video tutorial https://youtu.be/146AypcFvAU . Should be able to get this up and running with redis and websockets to handle subscriptions until the prisma2 version is ready.
https://github.com/ryanking1809/prisma2_subscriptions
Subscriptions aren't implemented yet.
I've opened up an issue to track it.
I'll edit this answer as soon as it's implemented in Prisma 2.

How to write maintainable JavaScript ala' Bash scripts with advanced reporting features?

I would like to write a script to execute backup procedure for multiple computers in an office. How can I write in a way that I can granually control execution path and also is easy to read and modify? Do I need OOP and SOLID?
The script should make sure that a computer is alive, if not WoL it and leave it in initial state after backup.
Also, the script should do a couple of basic health checks such as smartctl -H and after that execute rsync ... and brtbk ... commands to do the actual backup.
I would like the script to produce a one page report sent to an email address with a clear title indicating wether I should investigate or I can ignore the email.
I already tried to write this in vanilla JS with async/await but failed because of a complex configuration JSON I came up with.
var task = {
type: 'main',
config: {
host: '10.5.1.158',
mac: 'e0:d5:5e:ee:de:3d',
},
task: {
type: 'ensureAlive',
task: [
{
type: 'smartCheck',
dev: '/dev/sda'
},
{
type: 'smartCheck',
dev: '/dev/sdb'
},
{
type: 'failEarly',
task: [
{
type: 'rsync',
config: {
from: `root#{{config.ip}}:/home/VirtualBox\ VMs/a15:/backups/a15/vms/a15/`,
to: '/backups/a15/',
}
},
{
type: 'btrfsSnapshot',
config: {
dir: '/backups/a15/',
},
}
]
}
]
}
};
async function run(ctx, task) {
if (!task) {
return;
}
if (Array.isArray(task)) {
for (var i = 0; i < task.length; i++) {
await run(ctx, task[i]);
}
return;
}
var config = Object.assign({}, ctx.config || {}, task.config || {});
var f = ctx.getFunction(task.type);
try {
var result = await f(config);
task.output = result;
} catch (error) {
task.output = Output({ isOk: false, errorMessage: error.message, errorStack: error.stack })
}
var newCtx = Object.assign({}, ctx, { config });
await run(newCtx, task.task);
}
The recurring run function became too complex to understand and modify/add features.
I was expecting to get something as easy to read as this, no matter wether this is JSON or actual JavaScript. Pseudocode below:
async function a15(report) {
var wasAlive = wakeUp();
try {
await smartCheck();
} catch (error) {
report.addError(error);
}
try {
await smartCheck();
} catch (error) {
report.addError(error);
}
try {
await rsync();
await btrbk();
} catch (error) {
report.addError(error);
}
if (!wasAlive) {
shutDown();
}
}
What am I doing wrong? Is this even possible?
For extra clarification I would like to attach additional config layouts I tried.
Another config try which happened to be too complex to program. Since this config is flat, the main difficulty is related to passing a variable indicating that host is alive (at wakeUp) to the end of the config (at shutDown).
var a15: TaskDescription[] = [
{
type: 'wakeUp',
config: {
host: '10.5.1.252',
mac: 'e0:d5:5e:ee:de:3d'.replace(/:/g, ''),
timeout: '5',
user: 'root',
privateKey: '/Users/epi/.ssh/id_rsa',
},
},
{
type: 'smartCheck',
config: {
dev: '/dev/sda',
},
},
{
type: 'smartCheck',
config: {
dev: '/dev/sdb',
},
},
{
type: 'command',
configTemplateFromConfig: true,
config: {
command: 'rsync -a --inplace --delete -e ssh root#{{host}}:/home/santelab/VirtualBox\ VMs/a15:/mnt/samsung_m3/a15/ /backups/a15/'
},
},
{
type: 'command',
config: {
command: 'btrbk -c /mnt/samsung_m3/a15.conf run'
},
},
{
type: 'shutDown',
runIf: 'wasAlive',
config: {
host: '10.5.1.252',
mac: 'e0:d5:5e:ee:de:3d'.replace(/:/g, ''),
timeout: '5',
user: 'root',
privateKey: '/Users/epi/.ssh/id_rsa',
},
},
];
export interface TaskDescription {
type: string;
config?: TaskConfig;
configTemplateFromConfig?: boolean;
ignoreError?: boolean;
runIf?: string;
}
export type TaskConfig = {
[key: string]: string,
}
I think I made it.
There are 2 key concepts that are required:
never throw an error, always return a result that wraps error and value
use generators - yield magic
Here is a proof of concept for localhost writen in TypeScript. I could use JavaScript as well.
import { WakeUp, Config as WakeUpConfig, Result as WakeUpResult } from './WakeUp';
import { SmartCheck, Config as SmartCheckConfig } from './SmartCheck';
import { Command, Config as CommandConfig, Result as CommandResult } from './Command';
import * as I from './interfaces';
async function* localhost() {
var wakeUpResult = (yield WakeUp({ host: 'localhost', mac: 'e0:d5:5e:ee:de:3d', timeout: 5, tries: 20 })) as WakeUpResult;
if (wakeUpResult.error) { return; }
var echoResult = (yield Command({ command: `echo test` })) as CommandResult;
if (echoResult.error) { return; }
if (!wakeUpResult.value) {
yield Command({ command: 'echo shutdown' });
}
}
(async function () {
var iterator = localhost();
var lastResult: IteratorResult<any> = { value: undefined, done: false };
do {
lastResult = await iterator.next(lastResult.value);
} while (!lastResult.done);
})()
I think the core localhost() is easy to read and allows for easy modifications.

Sequelize Association throws an error in Create

I'm trying to do a simple association with sequelize in my NodeJS API, the idea is simple, I want to create a person and his type in the same moment. I try to follow the docs, but, when the create function is called Sequelize throws the error
"TypeError: Cannot read property 'getTableName' of undefined"
Bellow is the code used:
Models
Person.js
import Sequelize from 'sequelize';
export default (sequelize) => {
const Person = sequelize.define('person', {
email: { type: Sequelize.STRING },
nickname: { type: Sequelize.STRING(60) },
fullname: { type: Sequelize.STRING(60) },
observation: { type: Sequelize.TEXT },
}, { underscored: true, freezeTableName: true });
Person.associate = (models) => {
Person.hasOne(models.PersonType, {
foreignKey: 'person_id',
});
};
return Person;
};
PersonType.js
import Sequelize from 'sequelize';
export default (sequelize, DataTypes) => {
const PersonType = sequelize.define('person_type', {
type: { type: Sequelize.STRING(14), unique: true },
}, { underscored: true, freezeTableName: true });
PersonType.associate = (models) => {
PersonType.belongsTo(models.Person, {
foreignKey: 'person_id',
});
};
return PersonType;
};
index.js
import Sequelize from 'sequelize';
import console from 'console';
const database = process.env.DB_URL;
const sequelize = new Sequelize(database, {
dialect: 'postgres',
underscored: true,
});
const models = {
Person: sequelize.import('./person'),
PersonType: sequelize.import('./personType'),
};
Object.keys(models).forEach((modelName) => {
if ('associate' in models[modelName]) {
models[modelName].associate(models);
}
});
models.sequelize = sequelize;
models.Sequelize = Sequelize;
export default models;
The file where I try to execute the operation:
import models from '../models';
export default class PersonOperations {
constructor(db) {
this.db = db; // db here is the sequelize model of Person
}
create(person) {
return this.db.create({
email: person.email,
nickname: person.nickname,
observation: person.observation,
personType: {
type: person.personType.type,
},
}, {
include: [{
model: models.PersonType,
include: [person.personType],
}],
});
}
The error:
TypeError: Cannot read property 'getTableName' of undefined
at Function._validateIncludedElement (/home/~/node_modules/sequelize/lib/model.js:465:30)
at options.include.options.include.map.include (/home/~/node_modules/sequelize/lib/model.js:395:37)
at Array.map (<anonymous>)
at Function._validateIncludedElements (/home/~/node_modules/sequelize/lib/model.js:390:39)
I have already tried a lot of different things that I have found, but none of them helped me.
I am using freezeTableName, I have already tried to remove that, drop the database and create again, but the problem still persists.
Just Comment out the below code block from Person.js and run the code
Person.associate = (models) => {
Person.hasOne(models.PersonType, {
foreignKey: 'person_id',
});
};
Reason of error :
Here you are creating the circular dependecies , using
models.PersonType inside models.Person and then after using
models.Person inside models.PersonType
hasOne and belongsTo both are the same thing only diff is (READ) :
Player.belongsTo(Team) // `teamId` will be added on Player / Source model
Coach.hasOne(Team) // `coachId` will be added on Team / Target model

How to properly create defaults with apollo-link-state

I'm currently migrating an application I developed from redux to apollo. I'm following this example trying to implement apollo-link-state and apollo-cache-inmemory but I'm struggling to understand how their framework works. It would be great if someone could answer some questions, so here we go:
Use Case: Store modals information (basically wether it's open or not) in my cache memory
Here is my code:
// apollos.js
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { withClientState } from 'apollo-link-state';
import { HttpLink } from 'apollo-link-http';
import { ApolloLink } from 'apollo-link';
import { modalStateQuery } from "./common/queries/modal.query";
const httpLinkOptions = {
uri: 'http://localhost:8080/graphql',
};
const httpLink = new HttpLink(httpLinkOptions);
const cache = new InMemoryCache({
dataIdFromObject: o => o.id
});
const typeDefs = `
type Modal {
id: ID!
open: Boolean!
}
type Query {
modal(id: ID!): Modal
modals: [Modal]
}
`;
const defaults = {
modals: [
{
__typename: "Modal",
id: "login",
open: false
},
{
__typename: "Modal",
id: "signup",
open: false
}
]
};
const resolvers = {
Query: {
modal: (_, { id }, { cache }) => {
console.log("get modal");
try {
const data = cache.readQuery({ query: modalStateQuery.getOne, variables: { id } });
console.log("data", data);
} catch (e) {
console.log("error", e);
}
return null;
},
modals: (_, { }, { cache }) => {
console.log("Modal List Resolver"); // this is never logged
}
}
}
const stateLink = withClientState({
cache,
resolvers,
defaults,
typeDefs
});
const link = ApolloLink.from([stateLink, httpLink]);
const client = new ApolloClient({
link,
cache,
dataIdFromObject: o => o.id
});
export default client;
-
// modal.query.js
import gql from "graphql-tag";
export const modalStateQuery = {
getOne: gql`
query ModalState($id: String!) {
modal(id: $id) #client {
id
open
}
}`,
getAll: gql`
query {
modals #client {
id
open
}
}
`
};
-
// modal.js
// ...
// fetching both for test purposes
export default compose(
graphql(modalStateQuery.getOne, { name: "modal" }),
graphql(modalStateQuery.getAll, { name: "allModals" })
)(Modal);
Ok, now the questions:
The number one problem I'm having is with the modal($id: id) query. When I execute modalStateQuery.getAll the modals resolver is never called, but I still get the list I defined in defaults in my component. But when I execute modalStateQuery.getOne I always get the same error:
error Error: Can't find field modal({"id":"login"}) on object (ROOT_QUERY) {
"modals": [
{
"type": "id",
"generated": false,
"id": "login",
"typename": "Modal"
},
{
"type": "id",
"generated": false,
"id": "signup",
"typename": "Modal"
}
]
}.
at readStoreResolver (readFromStore.js:71)
at executeField (graphql.js:90)
at graphql.js:46
at Array.forEach (<anonymous>)
at executeSelectionSet (graphql.js:40)
at graphql (graphql.js:35)
at diffQueryAgainstStore (readFromStore.js:124)
at readQueryFromStore (readFromStore.js:37)
at InMemoryCache../node_modules/apollo-cache-inmemory/lib/inMemoryCache.js.InMemoryCache.read (inMemoryCache.js:84)
at InMemoryCache../node_modules/apollo-cache-inmemory/lib/inMemoryCache.js.InMemoryCache.readQuery (inMemoryCache.js:181)
What is this array it is showing to me? Why isn't there all the props I defined in defaults (like open: false)? Could it be something wrong with the way I create my defaults?
In the apollo-cache-inmemory docs it doesn't define any resolvers, it just says that you should query your data just like you are doing it in the backend, passing the variables.
Also, why does modalStateQuery.getAll works even though the resolver is never called? What if I do want that resolver to be called (Maybe I want to check my backend first to check permissions or smth)?
Another curious behavior I noticed: When executing the modal resolver, the id variable is always correct, even though I didn't explicitly pass it as variable in my component, but the Modal.js component does have an id props that I pass to it:
return <Modal id="login"><LoginForm /></Modal>;
It makes me believe that apollo already recognizes that the Modal.js is being called with an id prop and automatically passes it to the query as a variable. Is that correct? It does it for any variable?
Thanks!

Categories