Skip to content

Commit 06507f3

Browse files
authored
Merge pull request #4 from flybits/bug/new-instances-not-initialized
Bug/new instances not initialized
2 parents 094c94e + 6b207c2 commit 06507f3

5 files changed

Lines changed: 88 additions & 4 deletions

File tree

src/models/localizedModel.js

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ class LocalizedModel{
77
const model = this;
88
this._localizedProxy = new Proxy(this, {
99
set(target, prop, newVal){
10-
const attrMap = model._strMap[prop];
10+
var attrMap = model._strMap[prop];
11+
if(!attrMap && prop !== '_strMap' && prop !== '_localeKey' && prop !== '_localizedProxy'){
12+
attrMap = model._strMap[prop] = {};
13+
}
1114
if(attrMap){
1215
model._setLocalizedValue(prop, newVal);
1316
}
@@ -97,7 +100,10 @@ class LocalizedModel{
97100
return new Proxy(object, {
98101
set(target, prop, newVal){
99102
const resolvedAttrKey = `${attrKey}.${prop}`;
100-
const attrMap = model._strMap[resolvedAttrKey];
103+
var attrMap = model._strMap[resolvedAttrKey];
104+
if(!attrMap && prop !== '_strMap' && prop !== '_localeKey' && prop !== '_localizedProxy'){
105+
attrMap = model._strMap[resolvedAttrKey] = {};
106+
}
101107
if(attrMap){
102108
model._setLocalizedValue(resolvedAttrKey, newVal);
103109
}
@@ -153,6 +159,7 @@ class LocalizedModel{
153159
*/
154160
inflateLocales(attrKeyMap, arrIndex){
155161
var localeObj = {};
162+
var localeKeysMap = {};
156163

157164
Object.keys(attrKeyMap).forEach((cacheKey) => {
158165
var resolvedCacheKey = cacheKey;
@@ -162,6 +169,7 @@ class LocalizedModel{
162169
let attrMap = this._strMap[resolvedCacheKey];
163170
if(attrMap){
164171
Object.keys(attrMap).forEach(function(localeKey){
172+
localeKeysMap[localeKey] = true;
165173
const outputKey = attrKeyMap[cacheKey];
166174
if(!Object.prototype.hasOwnProperty.call(localeObj, localeKey)){
167175
localeObj[localeKey] = {};
@@ -171,6 +179,17 @@ class LocalizedModel{
171179
}
172180
})
173181

182+
Object.keys(localeKeysMap).forEach(function(localeKey){
183+
let localeMap = localeObj[localeKey]
184+
185+
Object.keys(attrKeyMap).forEach((cacheKey) => {
186+
const outputKey = attrKeyMap[cacheKey];
187+
if(!Object.prototype.hasOwnProperty.call(localeMap, outputKey)){
188+
localeMap[outputKey] = '';
189+
}
190+
})
191+
})
192+
174193
return localeObj;
175194
}
176195
}

src/utils/num.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
var NumUtil = {
2+
isNumber: function(val){
3+
return typeof val === 'number' && !isNaN(val);
4+
},
5+
isStrNumber: function(val){
6+
return NumUtil.isNumber(+val);
7+
}
8+
};
9+
10+
export default NumUtil;

src/utils/obj.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1+
import NumUtil from "./num";
2+
13
var ObjUtil = {
4+
isObject: function(obj){
5+
return typeof obj === 'object' && obj !== null;
6+
},
27
getByStr: function (obj, keyStr) {
38
// convert indexes to properties
49
keyStr = keyStr.replace(/\[(\w+)\]/g, '.$1');
@@ -7,7 +12,7 @@ var ObjUtil = {
712
var aKeys = keyStr.split('.');
813
for (var i = 0, n = aKeys.length; i < n; ++i) {
914
var key = aKeys[i];
10-
if (key in obj) {
15+
if (ObjUtil.isObject(obj) && key in obj) {
1116
obj = obj[key];
1217
} else {
1318
return;
@@ -26,7 +31,7 @@ var ObjUtil = {
2631
if (key in obj && i + 1 < n) {
2732
obj = obj[key];
2833
} else if (!(key in obj) && i + 1 < n) {
29-
obj[key] = {};
34+
obj[key] = NumUtil.isStrNumber(aKeys[i+1]) ? [] : {};
3035
obj = obj[key];
3136
} else {
3237
obj[key] = val;

tests/object.spec.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,30 @@ test('Update respective proxied locale values', () => {
8080
let serverPayload = appObj.toJSON();
8181
expect(serverPayload?.secondLevel?.localizations?.en?.header).toBe('englishtest');
8282
expect(serverPayload?.secondLevel?.localizations?.fr?.header).toBe('frenchtest');
83+
})
84+
85+
test('New instance setting attribute will serialize', () => {
86+
let appObj = new AppObject();
87+
appObj.secondLevelObj.header = 'first value';
88+
appObj.localize('fr');
89+
appObj.secondLevelObj.header = 'french value';
90+
let serverPayload = appObj.toJSON();
91+
expect(serverPayload?.secondLevel).toBeInstanceOf(Object)
92+
expect(serverPayload?.secondLevel?.localizations?.en?.header).toBe('first value')
93+
expect(serverPayload?.secondLevel?.localizations?.fr?.header).toBe('french value')
94+
})
95+
96+
test('Serialization is symmetrical across locales even for empty values', () => {
97+
let appObj = new AppObject();
98+
appObj.secondLevelObj.header = 'first value';
99+
appObj.localize('fr');
100+
appObj.secondLevelObj.header = 'french value';
101+
let serverPayload = appObj.toJSON();
102+
expect(serverPayload?.secondLevel).toBeInstanceOf(Object)
103+
expect(serverPayload?.secondLevel?.localizations?.en?.header).toBe('first value')
104+
expect(serverPayload?.secondLevel?.localizations?.en?.subHeader).toBe('');
105+
expect(serverPayload?.secondLevel?.localizations?.en?.description).toBe('');
106+
expect(serverPayload?.secondLevel?.localizations?.fr?.header).toBe('french value')
107+
expect(serverPayload?.secondLevel?.localizations?.fr?.subHeader).toBe('');
108+
expect(serverPayload?.secondLevel?.localizations?.fr?.description).toBe('');
83109
})

tests/toplevel.spec.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,28 @@ test('Update respective proxied locale values', () => {
7878
let serverPayload = appObj.toJSON();
7979
expect(serverPayload?.localizations?.en?.header).toBe('englishtest');
8080
expect(serverPayload?.localizations?.fr?.header).toBe('frenchtest');
81+
})
82+
83+
test('New instance setting attribute will serialize', () => {
84+
let appObj = new AppObject();
85+
appObj.header = 'first value';
86+
appObj.localize('fr');
87+
appObj.header = 'french value';
88+
let serverPayload = appObj.toJSON();
89+
expect(serverPayload?.localizations?.en?.header).toBe('first value')
90+
expect(serverPayload?.localizations?.fr?.header).toBe('french value')
91+
})
92+
93+
test('Serialization is symmetrical across locales even for empty values', () => {
94+
let appObj = new AppObject();
95+
appObj.header = 'first value';
96+
appObj.localize('fr');
97+
appObj.header = 'french value';
98+
let serverPayload = appObj.toJSON();
99+
expect(serverPayload?.localizations?.en?.header).toBe('first value');
100+
expect(serverPayload?.localizations?.en?.subHeader).toBe('');
101+
expect(serverPayload?.localizations?.en?.description).toBe('');
102+
expect(serverPayload?.localizations?.fr?.header).toBe('french value');
103+
expect(serverPayload?.localizations?.fr?.subHeader).toBe('');
104+
expect(serverPayload?.localizations?.fr?.description).toBe('');
81105
})

0 commit comments

Comments
 (0)