Uncaught Rally.data.ModelFactory.getModel(): Could not find registered factory for type: milestone - extjs

Trying to display Milestone for each release, but when trying to create DataStore for Milestone getting error
Uncaught Rally.data.ModelFactory.getModel(): Could not find registered factory for type: milestone
below is my code any ideas or suggestions on this
_getMileStones: function(startDate, endDate, project_id) {
var startDateFilter = Ext.create('Rally.data.QueryFilter', {
property: 'TargetDate',
operator: '>',
value: startDate
});
startDateFilter = startDateFilter.and({
property: 'TargetDate',
operator: '<',
value: endDate
});
startDateFilter = startDateFilter.and({
property: 'TargetDate',
operator: '!=',
value: null
});
startDateFilter = startDateFilter.and({
property: 'TargetDate',
operator: '!=',
value: null
});
var filters = startDateFilter;
Ext.create('Rally.data.wsapi.Store',{
model: 'milestone',
autoLoad: true,
filters: filters,
context: {
project: project_id,
projectScopeDown: true,
projectScopeUp: false
},
fetch: ['Name','FormattedID','DisplayColor'],
listeners: {
load: function(store,records) {
console.log("records values", records);
}
}
}, this);
},

The current stable rc3 release candidate of AppSDK2 predates milestones. They are not available in rc3. When I use rc3 I get the same error you get. If I switch to "x", in the app's config file, and use rab build to rebuild the app, the error goes away:
{
"name": "myapp",
"className": "CustomApp",
"server": "https://rally1.rallydev.com",
"sdk": "x",
"javascript": [
"App.js"
],
"css": [
"app.css"
]
}
Generally it is not recommend using "x" because it is constantly changes. It is not a stable version. But as long as you know that, you may use "x". The AppSDK next release may not be too far in the future, and it will include support for Milestones.
UPDATE: AppSDK2.0 GA has not been announced yet, but it is expected to be released soon. If you use "sdk":"2.0" you get Milestone data.
"x" returns Milestones, but it is a head version that is subject to constant changes. 2.0rc3 does not have Milestones.
You may choose to use 2.0 even though it is not formally available yet.
This app example:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
Ext.create('Rally.data.wsapi.Store',{
model: 'milestone',
autoLoad: true,
fetch: ['Name'],
listeners: {
load: function(store,records) {
console.log("records values", records);
}
}
}, this);
}
});
Along with this config:
{
"name": "milestones",
"className": "CustomApp",
"server": "https://rally1.rallydev.com",
"sdk": "2.0",
"javascript": [
"App.js"
],
"css": [
"app.css"
]
}
will return milestone data:

Related

How do i modify a raw data object returned by an ExtJS AJAX proxy into a JSON object to be consumed by a Tree Store

In an effort to create a treepanel, i configure it with a treestore whose AJAX proxy url receives json data i have no control of. But using Ext.data.reader.Json's transform property invokable before readRecords executes, gives an option to modify the passed raw (deserialized) data object from the AJAX proxy into a modified or a completely new data object. The transform config, gives the code snippet below:
Ext.create('Ext.data.Store', {
model: 'User',
proxy: {
type: 'ajax',
url : 'users.json',
reader: {
type: 'json',
transform: {
fn: function(data) {
// do some manipulation of the raw data object
return data;
},
scope: this
}
}
},
});
I would please like an example on how to go about modifying the return JSON object
[
{
"id": 3,
"attributes":
{},
"name": "user_one",
"login": "",
"email": "user_one#ats",
"phone": "0751223344",
"readonly": false,
"administrator": false,
"password": null
},
{
"id": 4,
"attributes":
{},
"name": "user_two",
"login": "",
"email": "user_two#ats",
"phone": "0751556677",
"readonly": false,
"administrator": false,
"password": null
}
]
into a JSON object fit for a treestore.
The hierarchical tree is to be rendered to show which user is under which admin using a condition administrator==true from the returned JSON, then a second AJAX request that returns that admin's users shown here.
[
{
"user_id": 3,
"admin_id": 1,
},
{
"user_id": 4,
"admin_id": 2,
}
]
Is the data nested at all? Otherwise why use a treepanel instead of a grid? To your question though, it'll depend on how you configure your treepanel but it would probably be something like this:
transform: {
fn: function(data) {
var treeRecords = Ext.Array.map(data, function(i){
return {
text: i.name,
leaf: true
//any other properties you want
}
});
var treeData = {
root: {
expanded: true,
children: treeRecords
}
};
return treeData;
},
scope: this
}

ExtJS 6 inherited hasMany-Relation nested loading

I try to setup a hasMany relationship and want load my main entity with all the associated models in a single request.
But that seems not to work with "hasMany" relations that is inherited.
I have a BaseModel that defines all relations and fields and a "normal" model that defines the proxy to load from.
These are my (relevant) models:
Ext.define('MyApp.model.BaseUser', {
"extend": "Ext.data.Model",
"uses": [
"MyApp.model.UserEmail",
"MyApp.model.Account"
],
"fields": [
{
"name": "name"
},
{
"name": "accountId",
"reference": {
"type": "MyApp.model.Account",
"role": "account",
"getterName": "getAccount",
"setterName": "setAccount",
"unique": true
}
}
]
"hasMany": [
{
"name": "emails",
"model": "MyApp.model.UserEmail"
}
],
});
Ext.define('MyApp.model.User', {
extend: "MyApp.model.BaseUser",
proxy: {
type: 'rest',
url : '/api/user',
reader: {
type: 'json',
rootProperty: 'data',
}
}
});
Ext.define('MyApp.model.UserEmail', {
extend: 'Ext.data.Model',
"fields": [
{
"name": "id",
"type": "int"
},
{
"name": "email",
"type": "string"
},
],
proxy: {
type: 'rest',
url : '/api/user/email',
reader: {
type: 'json',
rootProperty: 'data',
}
}
});
// MyApp.model.Account looks like MyApp.model.UserEmail
This is my server's response:
{
data: [
{
name: 'User Foo'
accountId: 50
account: {
id: 50,
balance: 0
},
emails: [
{
id: 70,
email: 'hello#world.de'
}
]
}
]
}
The "account" relation is working on the "normal" User Model and I can access it via the auto-generated method user.getAccount() as I expected.
Now I tried to access the users emails with the auto-generated methods:
// user is of 'MyApp.model.User'
user.emails(); // store
user.emails().first(); // null
user.emails().count(); // 0
It seems that the "emails"-relation models were not loaded into my user model. Am I accessing them the right way?
I can access them via user.data.emails. But this is an array of plain objects, not of UserEmail-Objects.
Can anyone give me some advice? Is nested loading supported with keyless associations?
Kind regards,
czed
Edit:
Clearified what I ment.
It should work. Here's a working fiddle. Check console for nested loaded data.

Why does Chutzpah only see the tests if they listed under "References" section and doesn't if they under "Tests"

I have a quite big solution with a few web module projects (they are kind of modules and they are copied into a common project which is the SPA). I started to write jasmine-typescript tests against my angular 1.5.8 code. In order to spare copying time I need to set up Chutzpah for every web project so I can test every module code.
I have the chutzpah.json below and this way when I select "Open in Browser" then I can see the tests.
{
"Framework": "jasmine",
"FrameworkVersion": "2",
"Compile": {"Mode": "External"},
"References": [
{
"Path": "../../where_angular_and_other_scripts_are_placed/",
"Includes": [ "*.js" ]
},
{
"Path": "../../where_angular-mocks_are_placed/",
"Includes": [ "*.js" ]
},
{
"Path": "../../CommonLibrary/",
"Includes": [ "*.js" ],
"Excludes": [ "*.Spec.js" ]
},
{
"Path": "app/modules/Framework/",
"Includes": [ "*.Spec.js" ]
}
]
}
If I change the file like below then there are no tests. I don't understand why. Chutzpah cannot manage that a solution has more than one chutzpah.json in different directories? According to the documentation it shouldn't be problem.
{
"Framework": "jasmine",
"FrameworkVersion": "2",
"Compile": {"Mode": "External"},
"References": [
{
"Path": "../../where_angular_and_other_scripts_are_placed/",
"Includes": [ "angular.js", "*.js" ]
},
{
"Path": "../../where_angular-mocks_are_placed/",
"Includes": [ "*.js" ]
},
{
"Path": "../../CommonLibrary/",
"Includes": [ "*.js" ],
"Excludes": [ "*.Spec.js" ]
}
],
"Tests": [
{
"Path": "app/modules/Framework/",
"Includes": [ "*.Spec.js" ]
}
]
}
Another issue with Chutzpah setup is that, it always says that angular is not defined. I have the code below and when I run it it says angular is not defined. If I remove the inject part then it runs. But, I need to mock things. I have the bad feeling the above configuration issue and the stuff below somehow connected.
describe("getActiveModules method", (): void =>
{
var RestangularMock: any;
var angularCommonCheckerService:AngularCommonCheckerService;
var dilibModuleService: IDiLibModuleService;
var $q: ng.IQService;
var allReturnObject: any;
beforeEach((): void =>
{
//#region Arrange
angular.mock.inject(($injector): void => {
$q = $injector.get("$q");
});
RestangularMock = jasmine.createSpyObj("Restangular", ["all", "post"]);
angularCommonCheckerService = new AngularCommonCheckerService();
dilibModuleService = new DilibModuleService(RestangularMock, angularCommonCheckerService);
var returnList: IModuleContract[] = [
<IModuleContract>{ id: 100, isActive: 1 },
<IModuleContract>{ id: 101, isActive: 1 },
];
var allReturnObject = <any>{
getList: (): IModuleContract[]> => {
var deferred = $q.defer();
deferred.resolve(returnList);
return deferred.promise;
}
};
spyOn(allReturnObject, "getList");
//#endregion
});
it("should call Restangular resource with given string", (): void =>
{
RestangularMock.all.and.returnValue(allReturnObject);
dilibModuleService.getActiveModules();
expect(RestangularMock.all).toHaveBeenCalledWith("FrameworkApp/Module/GetActiveModules");
expect(allReturnObject.getList).toHaveBeenCalledTimes(1);
});
Questions:
Why Chutzpah doesn't list tests when the test references listed under "Test"? Did I do something wrong?
Is the issue around inject connected to the configuration issue?
how can I debug Chutzpah and see what is included from the references and tests? It is enough to check the source of the generated html file?

LoopBack AngularJS extending User model

i'm facing some problems when using an extended user model in my AngularJS application.
here is my user.json:
{
"name": "user",
"base": "User",
"strict": false,
"idInjection": true,
"properties": {
"clientType": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [
{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
}
],
"methods": []
}
here is my model-config.json:
{
"_meta": {
"sources": [
"loopback/common/models",
"loopback/server/models",
"../common/models",
"./models"
]
},
"User": {
"dataSource": "mongo"
},
"AccessToken": {
"dataSource": "mongo",
"public": false
},
"ACL": {
"dataSource": "mongo",
"public": false
},
"RoleMapping": {
"dataSource": "mongo",
"public": false
},
"Role": {
"dataSource": "mongo",
"public": false
},
"Store": {
"dataSource": "mongo",
"public": true
},
"user": {
"dataSource": "mongo",
"public": true
}
}
this is my UserCtrl.js
angular.module('app.controllers.user', [])
.controller('UserCtrl', ['user', function (user) {
var vm = this;
vm.addUser = function () {
user.create({
firstName: vm.firstName,
lastName: vm.lastName,
email: vm.email,
password: vm.password,
userType: 'customer'
})
.$promise
.then(function (c) {
console.log('added user: ' + c.email);
});
};
}])
i'm getting the following error:
Error: [$injector:unpr] Unknown provider: userProvider <- user <- UserCtrl
if i use 'User' instead of 'user' it works, but it doesn't use my extended user-model with the specified ACL (READ for everyone)
i've read that you can specify var myUser = app.model.user to make sure that LoopBack uses the extended model. but i don't know how to do that in AngularJS since i specify the model as function parameter in the controller..
can you tell me how to use my extended user model within my AngularJS app?
thanks in advance!!
Do you have your user model generated inside Angular client library? If your application works when you use loopback auto-generated "User" model, then my best guess is that you have created your extended model "user", after you initially generated your angular services. If you are not using grunt task then you should regenerate angular services to update file with all changes and new models that you added since you last time generated the file.
Use lb-ng command to do it. As documentation suggests
For example, if your application has the standard LoopBack project layout, then in the /client sub-directory, enter these commands:
$ mkdir js
$ lb-ng ../server/server.js js/lb-services.js
You can find more information on the following link
http://docs.strongloop.com/display/public/LB/AngularJS+JavaScript+SDK
You need to define a Service, Factory, Provider, Value or Constant called 'user' in order for the service to be injectable in your controller. I do not see either of these in your post.
My suggestion is, if your extended user model is an instance of a class, then use a service:
app.service('user', fn);
If your extended user model is an object literal in JSON format, then use a factory:
app.factory('user', function() { return { ... }; });

How to initialize Ext.Direct?

I try to use Ext.Direct with the ExtJS 4 MVC structure, and I'm not able to add the provider.
I get the error Uncaught TypeError: Cannot call method 'addProvider' of undefined while calling addProvider:
Ext.Direct.addProvider(Ext.app.REMOTING_API);
I tried both in launch of the application and in initof the controller.
Ext.define('Dir.Application', {
require: [
'Ext.direct.*',
'Ext.data.*',
'Ext.grid.*'
],
launch: function(){
Ext.Direct.addProvider(Ext.app.REMOTING_API);
}
...
});
and
Ext.define('Dir.controller.Main', {
init: function(){
Ext.Direct.addProvider(Ext.app.REMOTING_API);
}
...
});
both give the same error.
Where is the correct location to put addProvider into the code ?
Update: applying the recommendations of #rixo.
Ext.define('Dir.Application', {
view:['Grid'],
requires: [
'Ext.direct.*',
'Ext.data.*',
'Ext.grid.*'
],
launch: function(){
Ext.Direct.addProvider(Ext.app.REMOTING_API);
}
...
});
My view is defining a store and a proxy:
Ext.define('Dir.view.Grid', {
extend: 'Ext.grid.Panel',
store: {
proxy: {
type: 'direct',
reader:{root: 'table'},
api: {
create: QueryDatabase.createRecord,
read: QueryDatabase.getResults,
update: QueryDatabase.updateRecords,
destroy: QueryDatabase.destroyRecord
}
}
...
}
Now the first error is OK, but I receiver an error complaining that QueryDatabase is not defined. It gets defined through the provider at Ext.Direct.addProvider(Ext.app.REMOTING_API); but it is not ready when the view is loaded through the views: [] declaration in the application definition.
Is there a way to get this working without nesting Ext.application inside Ext.onReady like in my solution?
No nesting would be better for the MVC way like explained here in the docs.
The require in your application definition won't do anything. It should be plural requires.
Also, you seem to have devised this in your own answer, but the name Ext.direct.Manager seems to be the favored by Sencha over Ext.Direct now.
Edit
According to the docs, you can set your direct functions using a string. Apparently, this is intended to solve exactly the kind of problems you've run into.
This should work and fix your issue:
api: {
create: 'QueryDatabase.createRecord',
read: 'QueryDatabase.getResults',
update: 'QueryDatabase.updateRecords',
destroy: 'QueryDatabase.destroyRecord'
}
Probably you are missing the API definition before calling the provider, take a look to this definition from Sencha's examples page
Ext.ns("Ext.app"); Ext.app.REMOTING_API = {
"url": "php\/router.php",
"type": "remoting",
"actions": {
"TestAction": [{
"name": "doEcho",
"len": 1
}, {
"name": "multiply",
"len": 1
}, {
"name": "getTree",
"len": 1
}, {
"name": "getGrid",
"len": 1
}, {
"name": "showDetails",
"params": ["firstName", "lastName", "age"]
}], ...}]
} };
It should be included as a javascript file inside your webpage
<script type="text/javascript" src="api.php"></script>
Something like this example.
Hope it helps.
Adding Direct providers is better done before the Application constructor runs:
Ext.define('Foo.Application', {
extend: 'Ext.app.Application',
requires: [
'Ext.direct.Manager',
'Ext.direct.RemotingProvider'
],
name: 'Foo',
constructor: function() {
Ext.direct.Manager.addProvider(...);
this.callParent(arguments);
}
});
Ext.application('Foo.Application');
I found this solution:
Ext.require([
'Ext.direct.RemotingProvider',
'Ext.direct.Manager',
'Ext.data.proxy.Direct'
]);
Ext.onReady(function(){
Ext.direct.Manager.addProvider(Ext.app.REMOTING_API);
Ext.application({
name: 'Dir',
extend: 'Dir.Application'
});
});
It doesn't look really nice, because it uses the ExtJS 4 application instantiation inside a Ext.onReady.
At least it works. Maybe there is a better solution ?

Resources