ReferenceError: Cannot access 'dtime' before initialization - grapesjs

working in grapesjs in component in js
//Date time
// Define a new custom component
editor.Components.addType('comp-with-js', {
model: {
defaults: {
dtime,
}
}
});
// Create a block for the component, so we can drop it easily
editor.Blocks.add('test-block', {
label: 'Test Date',
content:`
<div id="demo"></div>
`,
});
const dtime = function() {
const dt = new Date();
document.getElementById("demo").innerHTML = dt;
};
get error
ReferenceError: Cannot access 'dtime' before initialization

can't access dtime before initialization
//Date time
const dtime = function() {
const dt = new Date();
document.getElementById("demo").innerHTML = dt;
};
// Define a new custom component
editor.Components.addType('comp-with-js', {
model: {
defaults: {
dtime,
}
}
});
// Create a block for the component, so we can drop it easily
editor.Blocks.add('test-block', {
label: 'Test Date',
content:`
<div id="demo"></div>
`,
});

Related

Getting Invalid Hook Call Warning when trying to integrate React with exiting web application

We have a web application that is built using JSP pages. We are trying to migrate UI to React. Migration needs to be incremental as it's a huge application and we cannot migrate it completely in one go.
We are trying to run a poc to see how we will integrate react components in phased manner. We are able to integrate a vanilla react component (a static Select) following this React Docs page.
Problem comes when we started using useState hook. We started to get "Invalid Hook Call Warning".
We created a react app and created components there, it works as react application. We converted JSX components to plain JS using Babel cli (steps as mentioned on the React Doc Page).
Next we loaded React and React-DOM in the application through script tag as suggested on the page, except that we downloaded the script and referred from the file system.
<script src="https://unpkg.com/react#18/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#18/umd/react-dom.production.min.js" crossorigin></script>
<script type="text/javascript" src="<path to component JS>"></script>
When we tried to load the Select component in the target DIV element, we got the hook warning.
I extracted code into a sample html
<html>
<head>
<title>My Page</title>
</head>
<body>
<h1>Try React</h1>
<div id="targetDiv">
<h5>Place content here</h5>
</div>
<script type="text/javascript" src="./react/react.development.js"></script>
<script type="text/javascript" src="./react/react-dom.development.js"></script>
<script type="text/javascript" src="./react/components/core/coreSelect.js"></script>
<script type="text/javascript">
function getSelectOptions() {
const options = [];
options.push({ text: "Select...", value: "" });
options.push({ text: "Arizona", value: "AZ" });
options.push({ text: "Canada", value: "CA" });
options.push({ text: "Europe", value: "EU" });
options.push({ text: "Hawai", value: "HW" });
options.push({ text: "Mexico", value: "MX" });
options.push({ text: "New York", value: "NY" });
return options;
};
let selectArgs = {id:"mySelect", name: "mySelect", options: getSelectOptions(), value: "CA"};
let root = document.getElementById('targetDiv');
console.log({root});
ReactDOM.createRoot(root).render(Select(selectArgs));
</script>
</body>
</html>
Following is the content of coreSelect.js
var _slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i)
break;
}
} catch (err) {
_d = true; _e = err;
} finally {
try {
if (!_n && _i["return"])
_i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) { return arr; }
else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); }
else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
};
}();
function Select(_ref4) {
var id = _ref4.id,
name = _ref4.name,
value = _ref4.value,
options = _ref4.options;
var optArray = options ? options : [{ text: 'Select', value: '' }];
console.log("Before useState7", {useState});
var _useState7 = React.useState(options ? options : [{ text: 'Select', value: '' }]),
_useState8 = _slicedToArray(_useState7, 2),
optArray = _useState8[0],
setOptArray = _useState8[1];
console.log("Before useState9");
var _useState9 = React.useState(value),
_useState10 = _slicedToArray(_useState9, 2),
selectedVal = _useState10[0],
setSelectedVal = _useState10[1];
console.log("Before useState11");
var _useState11 = React.useState(""),
_useState12 = _slicedToArray(_useState11, 2),
effectiveClasses = _useState12[0],
setEffectiveClasses = _useState12[1];
var disabled = options && options.length > 0 ? false : true;
var onFocusClass = "active";
function processOnClick() {
if (!effectiveClasses || effectiveClasses.search(onFocusClass) < 0) {
setEffectiveClasses(function (prevClasses) {
var newClasses = (prevClasses ? prevClasses.trim() + " " : "") + onFocusClass;
return newClasses;
});
} else {
setEffectiveClasses(function (prevClasses) {
var newClasses = prevClasses.replace(onFocusClass).trim();
return newClasses;
});
}
}
return React.createElement(
"select",
// { id: id, name: name, className: "active", defaultValue: value, onClick: processOnClick, disabled: disabled },
{ id: id, name: name, className: effectiveClasses, defaultValue: selectedVal, onClick: processOnClick, disabled: disabled },
optArray && optArray.map(function (opt) {
var optValue = opt.value;
var optText = opt.text;
return React.createElement(
"option",
{ key: optValue, value: optValue },
optText
);
})
);
};
I have modified the JS file as generated from babel cli to not use imports/exports. I have verified on browser console that React, ReactDOM and Select component are available.
As an experiment I tried to run the command
ReactDOM.createRoot(document.getElementById('targetDiv')).render(Select({id:"mySelect", name: "mySelect", options: getSelectOptions(), value: "CA"}));
from browser console and I still got the react hook error.
I have been trying to search internet to find a solution but all available posts work with npm and try to resolve issues with react version mismatch, but I could not find any that would discuss problem with react integration with existing non-react applications.
Any help in this regard would be greatly appreciated.

Refresh Datatable in for:each loop: Lightning Web Components

I am having trouble refreshing a Datatable in my Lightning Web Component after updating a record. I am calling an onclick action on a button within the row, and imperatively calling an Apex method to update that record. I then call the refreshApex() to update the data being fed into the Datatable.
However, after the refreshApex(), the tables within the for:each are not being refreshed with new data.
The records are properly modified and reflect the changes properly when refreshing the entire page.
Note: The Task object is not supported in LWC, and I cannot use the updateRecord() method to update these records.
HTML:
<template>
<template if:true="{taskCompWrapperList}">
<!--<lightning-layout multiple-rows="false" pull-to-boundary="small">-->
<template for:each="{taskCompWrapperList}" for:item="taskTemplate">
<lightning-layout-item
key="{taskTemplate.taskSectionOrder}"
size="3"
class="slds-p-around_x-small"
>
<!-- Start bear tile -->
<lightning-card title="{taskTemplate.taskSectionTitle}">
<div class="slds-m-around_medium">
<template if:true="{taskTemplate.taskList}">
<lightning-datatable
key-field="Id"
data="{taskTemplate.taskList}"
onrowaction="{handleRowAction}"
columns="{columns}"
onsave="{handleSave}"
draft-values="{draftValues}"
>
</lightning-datatable>
</template>
<template if:true="{contact.error}">
<!-- handle Apex error -->
</template>
</div>
</lightning-card>
<!-- End bear tile -->
</lightning-layout-item>
</template>
<!--</lightning-layout>-->
</template>
</template>
Javascript:
import { LightningElement, api, wire ,track} from 'lwc';
import getTaskCompWrappers from '#salesforce/apex/ENT_Task_Utility.getTaskComponentWrapper';
import updateTask from '#salesforce/apex/ENT_Task_Utility.updateTask';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { updateRecord } from 'lightning/uiRecordApi';
import { refreshApex } from '#salesforce/apex';
const COLS = [
{
type: 'button',
label: 'Complete',
typeAttributes:
{
//iconName: 'action:preview',
label: 'Complete',
name: 'Complete',
title: 'Complete',
value: 'Complete',
variant: 'brand',
alternativeText: 'Complete'
}
},
{
type: 'button-icon',
label: 'Start',
typeAttributes:
{
iconName: 'action:approval',
//label: 'Complete',
name: 'Start',
title: 'Start',
value: 'Start',
variant: 'success',
alternativeText: 'Start',
}
},
{
type: "button",
typeAttributes:
{
label: 'View',
name: 'View',
title: 'View',
disabled: false,
value: 'view',
iconPosition: 'left'
}
},
{
type: "button",
typeAttributes:
{
label: 'Edit',
name: 'Edit',
title: 'Edit',
disabled: false,
value: 'edit',
iconPosition: 'left'
}
},
//{ label: 'Complete', fieldName: 'Task_Complete__c', editable: true },
{ label: 'Status', fieldName: 'Status', type: 'picklist', editable: true },
{ label: 'Completed', fieldName: 'Completed', type: 'boolean', editable: true },
{ label: 'Owner', fieldName: 'OwnerId', editable: true },
{ label: 'Subject', fieldName: 'Subject' },
{ label: 'Due Date', fieldName: 'ActivityDate', type: 'date' }
];
export default class ENT_Task_Utility_LWC extends LightningElement {
#api objApiName;
#api recordId;
#track testMessage = 'Test Failed :c';
#track error;
#track columns = COLS;
#track draftValues = [];
taskCompWrapperList;
#track error;
//#wire(getTasks, {recordId: '$recordId'}) taskList;`
#wire(getTaskCompWrappers, {recordId: '$recordId', objApiName: '$objApiName'})
taskCompWrapperListWire({ error, data }) {
if (data) {
this.taskCompWrapperList = data;
this.error = undefined;
} else if (error) {
this.error = error;
this.taskCompWrapperList = undefined;
}
}
updateTaskValues (taskId, taskStatus) {
// eslint-disable-next-line no-console
console.log('updateTaskValues hit');
for(var counter = 0; counter < this.taskCompWrapperList.length; counter++) {
// eslint-disable-next-line no-console
console.log('taskWrapper: ' + this.taskCompWrapperList[counter]);
for(var counter2 = 0; counter2 < this.taskCompWrapperList[counter].taskList.length; counter2++) {
// eslint-disable-next-line no-console
console.log('task: ' + this.taskCompWrapperList[counter].taskList[counter2]);
if(this.taskCompWrapperList[counter].taskList[counter2].Id == taskId)
{
this.dispatchEvent(
new ShowToastEvent({
title: 'Task Id Found!',
message: this.taskCompWrapperList[counter].taskList[counter2].Id,
variant: 'success'
})
);
this.taskCompWrapperList[counter].taskList[counter2].Status = taskStatus;
}
}
}
}
handleRowAction(event) {
//TODO
}
}
Apex methods:
#AuraEnabled(cacheable=true)
global static List<Task> getTasks(String recordId)
{
return [SELECT Id, Subject, OwnerId FROM Task WHERE WhatId = :recordId];
}
#AuraEnabled(cacheable=true)
global static List<ENT_Task_Comp_Wrapper> getTaskComponentWrapper(String recordId, String objApiName)
{
List<Task_Template__c> taskTemplateList = [SELECT Id, Task_Component_Section_Order__c, Task_Component_Section_Title__c, (SELECT Id FROM Task_Template_Items__r)
FROM Task_Template__c
WHERE Active__c = true AND sObject__c = :objApiName ORDER BY Task_Component_Section_Order__c ASC];
List<Task> taskList = [SELECT Id, Task_Template_Item__c, OwnerId, Owner.Name, Subject, Description, Status, ActivityDate, Task_Complete__c FROM TasK WHERE WhatId = :recordId];
List<ENT_Task_Comp_Wrapper> taskCompWrapperList = new List<ENT_Task_Comp_Wrapper>();
for(Task_Template__c taskTemplate : taskTemplateList)
{
ENT_Task_Comp_Wrapper taskCompWrapper = new ENT_Task_Comp_Wrapper();
taskCompWrapper.taskSectionTitle = taskTemplate.Task_Component_Section_Title__c;
taskCompWrapper.taskSectionOrder = (Integer)taskTemplate.Task_Component_Section_Order__c;
taskCompWrapper.taskList = new List<Task>();
for(Task currentTask : taskList)
{
for(Task_Template_Item__c taskTemplateItem : taskTemplate.Task_Template_Items__r)
{
if(taskTemplateItem.Id == currentTask.Task_Template_Item__c)
{
taskCompWrapper.taskList.add(currentTask);
}
}
}
taskCompWrapperList.add(taskCompWrapper);
}
System.debug(taskCompWrapperList);
return taskCompWrapperList;
}
#AuraEnabled
global static void updateTask(String taskId, String newStatus)
{
System.debug(taskId);
Task taskToUpdate = new Task(Id = taskId, Status = newStatus);
update taskToUpdate;
//update taskToUpdate;
}
#AuraEnabled
global static void updateTask(String taskId, String newStatus)
{
System.debug(taskId);
Task taskToUpdate = new Task(Id = taskId, Status = newStatus);
update taskToUpdate;
//update taskToUpdate;
}
In your JS code you have imported refreshApex
by using this line import { refreshApex } from '#salesforce/apex';
but you didn't assigned to any wire method. Hence data is not refreshed
Please refer this documentation.
To refresh a wired method, pass the argument the wired method receives (which is the wired value) to refreshApex(). In this sample code, the wired method is taskCompWrapperListWire. Hold on to the value provisioned by the wire service and pass it to refreshApex().
#wire(getTaskCompWrappers, {recordId: '$recordId', objApiName: '$objApiName'})
taskCompWrapperListWire({ error, data }) {
if (data) {
this.taskCompWrapperList = data;
this.error = undefined;
} else if (error) {
this.error = error;
this.taskCompWrapperList = undefined;
}
}
And then use refreshApex() as below:
refreshApex(this.taskCompWrapperListWire);
Update you code as below
updateTaskValues({
taskId: this.taskId,
taskStatus: this. taskStatus
})
.then(() => {
// your code logic
refreshApex(this.taskCompWrapperListWire);
})
.catch((error) => {
this.message = 'Error received: code' + error.errorCode + ', ' +
'message ' + error.body.message;
});
you probably need to wait for next release to have a correct way to handle such situation.
You are getting record through uiRecordApi and updating through Apex if I'm correct.
Then you would need to use getRecordNotifyChange() available in Winter 21 release.
Apart from the answer provided by Sudarshan, you should also define taskCompWrapperList as a reactive property to make it rerender when the property is updated.
#track taskCompWrapperList = [];

embed code twitter on Tinymce 4

I am adding a plugin which insert twitter embed code. the problem is that I can see the tweet on the editor but not in the source code and preview. And I can't save it. I saw in forum that I have to add 'http:' to '//platform.twitter.com/widgets.js' and put it before , unfortunately, it's not working. This is the code I put:
tinymce.PluginManager.add('twitter', function(editor, url) {
editor.on('init', function (args) {
editor_id = args.target.id;
});
editor.addButton('twitter', {
text: 'Twitter',
icon: false,
onclick: function () {
editor.windowManager.open({
title: 'Twitter Embed',
body: [
{ type: 'textbox',
size: 40,
height: '100px',
name: 'twitter',
label: 'twitter'
}
],
onsubmit: function(e) {
var embedCode = e.data.twitter;
var script = embedCode.match(/<script.*<\/script>/)[0];
var scriptSrc = script.match(/".*\.js/)[0].split("\"")[1];
console.log(script);
var sc = document.createElement("script");
sc.setAttribute("src", "https:"+scriptSrc);
sc.setAttribute("type", "text/javascript");
var iframe = document.getElementById(editor_id + "_ifr");
var iframeHead = iframe.contentWindow.document.getElementsByTagName('head')[0];
var iframeBody = iframe.contentWindow.document.getElementsByTagName('body')[0];
embedCode1 = embedCode.replace('//platform.twitter.com/widgets.js','https://platform.twitter.com/widgets.js');
iframeBody.appendChild(sc);
editor.insertContent(embedCode1);
iframeHead.appendChild(sc);
// setTimeout(function() {
// iframe.contentWindow.twttr.widgets.load();
// }, 1000)
}
});
}
});
});

Updating highcharts dynamically with json response

I am trying to draw highcharts with the json response, however I can able to draw for the first time, but unable to update the series with new data
function get_chart(data) {
//alert('hello..' + data);
return {
xAxis: {
type: 'datetime',
labels: {
formatter: function() {
var monthStr = Highcharts.dateFormat('%b', this.value);
var firstLetter = monthStr.substring(0, 1);
return firstLetter;
}
}
},
title: {
text: data.measurementName
},
chart: {
height: 300,
width: 500,
type: 'column',
zoomType: 'x'
},
credits: {
enabled: false
},
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function() {
console.log ('Category: '+ this.category +', value: '+ this.y);
}
}
}
}
},
series: [{
name: 'Hours',
data: (function() {
var chart = [{key:data.measurementName, values:[]}];
var i = 0;
if(typeof(data) == 'string')return chart;
for(n in data.values){
data.values[n].snapshot = new Date(data.values[n].snapshot);
data.values[n].value = parseInt(data.values[n].value);
}
chart[0].values = data.values.map(function(arrayObj){
return [arrayObj.value]
});
return chart[0].values;
})()
}]
};
}
and I am calling this function like
$scope.renderChart = function(measurement){
$scope.showChart = false;
restApp.getMeasurementForCompID(comp.id, measurement.id).then(function(data){
console.log(data);
$scope.example_chart = get_chart(data);
console.log($scope.example_chart);
$scope.showChart = true;
});
}
Here getMeasurementForCompID is another function which gets the data from database.
What is the problem here? any help..
I used https://github.com/pablojim/highcharts-ng
I just alter the data object and the highcharts reflects the change.

Rally App SDK getting object ID of feature

var showAssignedProgram = 1;
var value = null;
var showIterationCombo = 0;
var iterationComboValue = null;
var lumenize = window.parent.Rally.data.lookback.Lumenize;
var iterationComboField = null;
var iterationRecord = myMask = null;
var setOfStories = setOfFeatures = null;
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
//Write app code here
Ext.state.Manager.setProvider(
new Ext.state.CookieProvider({ expires: new Date(new Date().getTime()+(10006060247)) })
);
app = this;
var that = this;
console.log("launch");
// get the project id.
this.project = this.getContext().getProject().ObjectID;
// get the release (if on a page scoped to the release)
var tbName = getReleaseTimeBox(this);
var configs = [];
configs.push({ model : "Release",
fetch : ['Name', 'ObjectID', 'Project', 'ReleaseStartDate', 'ReleaseDate' ],
filters:[]
});
configs.push({ model : "Iteration",
fetch : ['Name', 'ObjectID', 'Project', 'StartDate', 'EndDate' ],
filters:[]
});
async.map( configs, this.wsapiQuery, function(err,results) {
that.releases = results[0];
that.iterations = results[1];
if (showAssignedProgram)
that.createAssignedProgramCombo();
that.createIterationCombo(that.iterations);
});
},
wsapiQuery : function( config , callback ) {
Ext.create('Rally.data.WsapiDataStore', {
autoLoad : true,
limit : "Infinity",
model : config.model,
fetch : config.fetch,
filters : config.filters,
listeners : {
scope : this,
load : function(store, data) {
callback(null,data);
}
}
});
},
createAssignedProgramCombo : function() {
// assigned Program (if set to true)
this.assignedProgramCombo = Ext.create("Rally.ui.combobox.FieldValueComboBox", {
model : "PortfolioItem/Feature",
field : "AssignedProgram",
stateful : true,
stateId : "assignedProgramCombo",
noData: false,
listeners:{
scope: this,
change: function(field,eOpts){
if(value!="" && value!=null)
{
this.afterCollapse(fieldValue,value);
}
}
}
});
this.add(this.assignedProgramCombo);
},
createIterationCombo: function(iterationRecords){
//console.log("Iteration records ",iterationRecords);
iterationRecord = iterationRecords;
var iterations = _.map(iterationRecords, function(rec){return {name: rec.get("Name"), objectid: rec.get("ObjectID"), startDate: new Date(Date.parse(rec.get("StartDate")))};});
console.log('iterations', iterations);
iterations = _.uniq(iterations, function(r){return r.name;});
iterations = _.sortBy(iterations, function(rec){return rec.StartDate;}).reverse();
var iterationStore = Ext.create('Ext.data.Store', {
fields: ['name','objectid'], data : iterations
});
var cb = Ext.create('Ext.form.ComboBox',{
fieldLabel: 'Iterations',
store: iterationStore,
queryMode: 'local',
displayField: 'name',
valueField: 'name',
listeners:{
scope: this,
change: function(field, eOpts){
console.log('field ', field, ' eOpts ',eOpts);
iterationComboValue = eOpts;
iterationComboField = field;
},
collapse: function(field, eOpts){
this.afterCollapse(field,eOpts);
}
}
});
this.add(cb);
},
afterCollapse: function(field,eOpts){
var r = [];
_.each(field.getValue().split(","), function(rn){
var matching_iterations = _.filter(iterationRecord, function(r){return rn == r.get("Name");});
var uniq_iterations = _.uniq(matching_iterations, function(r){return r.get("Name");});
_.each(uniq_iterations,function(iteration){r.push(iteration);});
});
if(r.length>0){
myMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."});
myMask.show();
this.selectedIterations = r;
this.queryFeatures(r);
}
},
queryFeatures: function(iterations){
var that = this;
var filter = null;
if (showAssignedProgram && this.assignedProgramCombo.getValue() != null && this.assignedProgramCombo.getValue() != "") {
console.log("assingedValue",this.assignedProgramCombo.getValue());
filter = Ext.create('Rally.data.QueryFilter', {
property: 'AssignedProgram',
operator: '=',
value: this.assignedProgramCombo.getValue()
});
}
else{
_.each(iterations, function(iteration, i){
var f = Ext.create('Rally.data.QueryFilter', {
property: 'Iteration.Name',
operator: '=',
value: iteration.get("Name")
});
filter = i === 0 ? f : filter.or(f);
});
}
console.log("filter",filter.toString());
var configs = [];
configs.push({
model: 'PortfolioItem/Feature',
fetch: ['ObjectID','FormattedID','UserStories' ],
filters: [filter],
listeners: {
load: function(store, features) {
setOfFeatures = features;
console.log("# features",features.length,features);
that.StartDate = that.startDate(iterations);
that.start = _.min(_.pluck(iterations,function(r) { return r.get("StartDate");}));
isoStart = new lumenize.Time(that.start).getISOStringInTZ("America/Chicago");
console.log("isoStart1",isoStart);
that.end = _.max(_.pluck(iterations,function(r) { return r.get("EndDate");}));
that.iterations = iterations;
console.log('End date ',that.end);
// that.getStorySnapshotsForFeatures( features, iterations);
}
}
});
configs.push({
model: 'HierarchicalRequirement',
limit: 'Infinity',
fetch: ['Name','Iteration','ObjectID','Feature'],
filters: [{
property: 'Iteration.Name',
operator: '=',
value: iterationComboValue
}],
listeners: {
load: function(store, stories){
setOfStories = stories;
console.log('Iteration combo value is ', iterationComboValue);
console.log("# stories ",stories.length,stories);
}
}
});
async.map(configs, this.wsapiQuery, function(err,results){
setOfFeatures = results[0];
console.log("# features",setOfFeatures.length,setOfFeatures);
that.StartDate = that.startDate(iterations);
that.start = _.min(_.pluck(iterations,function(r) { return r.get("StartDate");}));
isoStart = new lumenize.Time(that.start).getISOStringInTZ("America/Chicago");
that.end = _.max(_.pluck(iterations,function(r) { return r.get("EndDate");}));
that.iterations = iterations;
//Here is the problem
setOfStories = results[1];
var stories = _.map(setOfStories, function(story){ return {name: story.get("Name"),fid: story.get("Feature").ObjectID,objectid: story.get("ObjectID")};}); //throws error
console.log('stories ',setOfStories);
var features = _.map(setOfFeatures, function(feature){return {name: feature.get("Name"), fid: feature.get("ObjectID")};});
console.log('features ',setOfFeatures);
var candidateStories = [];
_.each(stories, function(story){_.each(features, function(feature){
if(story.fid == feature){
candidateStories.push(story);
}
});});
console.log('candidate stories ',candidateStories.length,candidateStories);
if(candidateStories!=null){
that.getStorySnapShotsForFeatures(candidateStories);
}
//create snapshot store based on candidateStories.
});
},
getStorySnapShotsForFeatures: function(stories){
var snapshots = [];
var that = this;
async.map(stories, this.readStorySnapshots,function(err,results){
console.log('results ',results);
});
},
readStorySnapshots: function(parent,callback){
console.log('inside story snapshots ');
Ext.create('Rally.data.lookback.SnapshotStore',{
limit: 'Infinity',
autoLoad: true,
listeners:{
scope: this,
load: function(store,data,success){
callback(null,data);
}
},
fetch: ['ObjectID'],
filters:[{
property: 'ObjectID',
operator: 'in',
value: ['ObjectID']
},
{
property: '__At',
operator: '=',
value: 'current'
}]
});
},
startDate: function(iterations){
var start = _.min(_.pluck(iterations, function(r){return r.get("StartDate");}));
return Rally.util.DateTime.toIsoString(start, false);
}
});
In the async.map callback function, when setOfStories are returned, I try to map the name, fid, and objectID to a new array. But for some reason, the fid: story.get("Feature").ObjectID gives an error saying get("") is null. But just before returning the array, when I console log story.get("Feature").ObjectID the correct value is printed, but somehow when I try to return the same value, it generates an error.
The field on HierarchicalRequirement for its PI parent is called PortfolioItem (since the PI types are customizable- feature just happens to be the default name of the lowest level one).
story.get('PortfolioItem').ObjectID

Resources