Skip to content
This repository was archived by the owner on Dec 9, 2021. It is now read-only.

Commit 78d5231

Browse files
author
rsavian
committed
Fixed issue with arrays having the same data for every item in the array when instantiated directly on the property. Fixed issue with child models not actually being cloned into new objects when .clone() is called on the parent model.
1 parent c847580 commit 78d5231

File tree

1 file changed

+51
-43
lines changed

1 file changed

+51
-43
lines changed

ts/model/BaseModel.ts

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,11 @@ class BaseModel extends BaseObject implements IBaseModel
8080
* @static
8181
* @readonly
8282
*/
83-
public static IS_BASE_MODEL:boolean = true;
83+
public static readonly IS_BASE_MODEL:boolean = true;
8484

8585
/**
8686
* @property sjsOptions
8787
* @type {IBaseModelOptions}}
88-
* @readonly
8988
* @public
9089
*/
9190
protected sjsOptions:IBaseModelOptions = {
@@ -122,39 +121,43 @@ class BaseModel extends BaseObject implements IBaseModel
122121
// Ignore the sjsId property because it is set in the BaseObject constructor and we don't want to update it.
123122
if (propertyName !== 'sjsId')
124123
{
125-
const currentData = this[propertyName];
126-
const newData = data[propertyName];
127-
const propertyData = (newData !== void 0) ? newData : currentData;
124+
const propertyData = this[propertyName];
125+
const updateData = data[propertyName];
126+
const dataToUse = (updateData !== void 0) ? updateData : propertyData;
128127

129-
this._updatePropertyWithNewData(propertyName, propertyData);
128+
this._updatePropertyWithDataPassedIn(propertyName, dataToUse);
130129
}
131130
});
132131

133132
return this;
134133
}
135134

136135
/**
137-
* Add the newData to the property
136+
* Adds the updateData to the property
138137
*
139-
* @method _updatePropertyWithNewData
138+
* @method _updatePropertyWithDataPassedIn
140139
* @param propertyName
141-
* @param newData
140+
* @param updateData
142141
* @protected
143142
*/
144-
protected _updatePropertyWithNewData(propertyName:any, newData:any):void
143+
protected _updatePropertyWithDataPassedIn(propertyName:any, updateData:any):void
145144
{
146-
// If the current property on the model is an array and the newData is an array.
147-
if ((this[propertyName] instanceof Array === true) && (newData instanceof Array === true))
145+
// If the current property on the model is an array and the updateData is an array.
146+
if ((this[propertyName] instanceof Array === true) && (updateData instanceof Array === true))
148147
{
149-
const isCurrentValueAnUninstantiatedBaseModel = (typeof this[propertyName][0] === 'function' && this[propertyName][0].IS_BASE_MODEL === true);
150-
const isNewValueAnUninstantiatedBaseModel = (typeof newData[0] === 'function' && newData[0].IS_BASE_MODEL === true);
148+
const isPropertyDataValueAnUninstantiatedBaseModel = (typeof this[propertyName][0] === 'function' && this[propertyName][0].IS_BASE_MODEL === true);
149+
const isUpdateDataValueAnUninstantiatedBaseModel = (typeof updateData[0] === 'function' && updateData[0].IS_BASE_MODEL === true);
151150

152-
// If the current data and the new data are both uninstantiated BaseModel we don't want to continue.
153-
if ((isCurrentValueAnUninstantiatedBaseModel === true && isNewValueAnUninstantiatedBaseModel === true) === false)
151+
if (isPropertyDataValueAnUninstantiatedBaseModel === false)
154152
{
155-
const baseModelOrUndefined = this[propertyName][0];
156-
157-
this[propertyName] = newData.map(data => this._updateData(baseModelOrUndefined, data));
153+
this[propertyName] = updateData.map(data => this._updateData(null, data));
154+
}
155+
else if (isPropertyDataValueAnUninstantiatedBaseModel === true && isUpdateDataValueAnUninstantiatedBaseModel === false)
156+
{
157+
// If the property data is an uninstantiated BaseModel then we assume the update data passed in
158+
// needs to be create as that BaseModel Class.
159+
const baseModel = this[propertyName][0];
160+
this[propertyName] = updateData.map(data => this._updateData(baseModel, data));
158161
}
159162
else
160163
{
@@ -163,47 +166,51 @@ class BaseModel extends BaseObject implements IBaseModel
163166
}
164167
else
165168
{
166-
this[propertyName] = this._updateData(this[propertyName], newData);
169+
this[propertyName] = this._updateData(this[propertyName], updateData);
167170
}
168171
}
169172

170173
/**
171-
* TODO: YUIDoc_comment
172-
*
173174
* @method _updateData
174-
* @param keyValue
175-
* @param newData
175+
* @param propertyData
176+
* @param updateData
176177
* @protected
177178
*/
178-
protected _updateData(keyValue:any, newData:any):any
179+
protected _updateData(propertyData:any, updateData:any):any
179180
{
180-
if (this.sjsOptions.expand === false && typeof newData === 'function' && newData.IS_BASE_MODEL === true)
181+
let returnData:any = null;
182+
183+
if (this.sjsOptions.expand === false && typeof updateData === 'function' && updateData.IS_BASE_MODEL === true)
181184
{
182-
// If newData is a function and has an IS_BASE_MODEL static property then it must be a child model and we need to return null
185+
// If updateData is a function and has an IS_BASE_MODEL static property then it must be a child model and we need to return null
183186
// so it cleans up the BaseModel functions on the property.
184187
// To create empty model(s) pass { expand: true } for the options.
185188
return null;
186189
}
187190

188-
if (typeof keyValue === 'function' && keyValue.IS_BASE_MODEL === true)
191+
if (typeof propertyData === 'function' && propertyData.IS_BASE_MODEL === true && updateData)
192+
{
193+
// If the propertyData is an instance of a BaseModel class and has not been created yet.
194+
// Instantiate it and pass in the updateData to the constructor.
195+
returnData = new propertyData(updateData, this.sjsOptions);
196+
}
197+
else if ((propertyData instanceof BaseModel) === true)
189198
{
190-
// If the property is an instance of a BaseModel class and has not been created yet.
191-
// Instantiate it and pass in the newData to the constructor.
192-
keyValue = new keyValue(newData, this.sjsOptions);
199+
// If propertyData is an instance of a BaseModel class and has already been created.
200+
// Call the update method and pass in the updateData.
201+
returnData = propertyData.update(updateData);
193202
}
194-
else if ((keyValue instanceof BaseModel) === true)
203+
else if ((updateData instanceof BaseModel) === true)
195204
{
196-
// If property is an instance of a BaseModel class and has already been created.
197-
// Call the update method and pass in the newData.
198-
keyValue.update(newData);
205+
returnData = updateData.clone();
199206
}
200207
else
201208
{
202-
// Else just assign the newData to the property.
203-
keyValue = newData;
209+
// Else just return the updateData to the property.
210+
returnData = updateData;
204211
}
205212

206-
return keyValue;
213+
return returnData;
207214
}
208215

209216
/**
@@ -213,7 +220,7 @@ class BaseModel extends BaseObject implements IBaseModel
213220
* @returns {any}
214221
* @public
215222
* @example
216-
* let obj = carModel.toJSON();
223+
* const obj = carModel.toJSON();
217224
*/
218225
public toJSON():any
219226
{
@@ -228,7 +235,7 @@ class BaseModel extends BaseObject implements IBaseModel
228235
* @returns {string}
229236
* @public
230237
* @example
231-
* let str = carModel.toJSONString();
238+
* const str = carModel.toJSONString();
232239
*/
233240
public toJSONString():string
234241
{
@@ -242,8 +249,8 @@ class BaseModel extends BaseObject implements IBaseModel
242249
* @param json {string}
243250
* @public
244251
* @example
245-
* let str = '{"make":"Tesla","model":"Model S","year":2014}'
246-
* let carModel = new CarModel();
252+
* const str = '{"make":"Tesla","model":"Model S","year":2014}'
253+
* const carModel = new CarModel();
247254
* carModel.fromJSON(str);
248255
*/
249256
public fromJSON(json:string):any
@@ -262,14 +269,15 @@ class BaseModel extends BaseObject implements IBaseModel
262269
* @returns {BaseModel}
263270
* @public
264271
* @example
265-
* let clone = carModel.clone();
272+
* const clone = carModel.clone();
266273
*/
267274
public clone():BaseModel
268275
{
269276
const clonedBaseModel:BaseModel = new (<any>this).constructor(this);
270277

271278
return clonedBaseModel;
272279
}
280+
273281
}
274282

275283
export default BaseModel;

0 commit comments

Comments
 (0)