Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions src/models/localizedModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ class LocalizedModel{
const model = this;
this._localizedProxy = new Proxy(this, {
set(target, prop, newVal){
const attrMap = model._strMap[prop];
var attrMap = model._strMap[prop];
if(!attrMap && prop !== '_strMap' && prop !== '_localeKey' && prop !== '_localizedProxy'){
attrMap = model._strMap[prop] = {};
}
if(attrMap){
model._setLocalizedValue(prop, newVal);
}
Expand Down Expand Up @@ -97,7 +100,10 @@ class LocalizedModel{
return new Proxy(object, {
set(target, prop, newVal){
const resolvedAttrKey = `${attrKey}.${prop}`;
const attrMap = model._strMap[resolvedAttrKey];
var attrMap = model._strMap[resolvedAttrKey];
if(!attrMap && prop !== '_strMap' && prop !== '_localeKey' && prop !== '_localizedProxy'){
attrMap = model._strMap[resolvedAttrKey] = {};
}
if(attrMap){
model._setLocalizedValue(resolvedAttrKey, newVal);
}
Expand Down Expand Up @@ -153,6 +159,7 @@ class LocalizedModel{
*/
inflateLocales(attrKeyMap, arrIndex){
var localeObj = {};
var localeKeysMap = {};

Object.keys(attrKeyMap).forEach((cacheKey) => {
var resolvedCacheKey = cacheKey;
Expand All @@ -162,6 +169,7 @@ class LocalizedModel{
let attrMap = this._strMap[resolvedCacheKey];
if(attrMap){
Object.keys(attrMap).forEach(function(localeKey){
localeKeysMap[localeKey] = true;
const outputKey = attrKeyMap[cacheKey];
if(!Object.prototype.hasOwnProperty.call(localeObj, localeKey)){
localeObj[localeKey] = {};
Expand All @@ -171,6 +179,17 @@ class LocalizedModel{
}
})

Object.keys(localeKeysMap).forEach(function(localeKey){
let localeMap = localeObj[localeKey]

Object.keys(attrKeyMap).forEach((cacheKey) => {
const outputKey = attrKeyMap[cacheKey];
if(!Object.prototype.hasOwnProperty.call(localeMap, outputKey)){
localeMap[outputKey] = '';
}
})
})

return localeObj;
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/utils/num.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
var NumUtil = {
isNumber: function(val){
return typeof val === 'number' && !isNaN(val);
},
isStrNumber: function(val){
return NumUtil.isNumber(+val);
}
};

export default NumUtil;
9 changes: 7 additions & 2 deletions src/utils/obj.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import NumUtil from "./num";

var ObjUtil = {
isObject: function(obj){
return typeof obj === 'object' && obj !== null;
},
getByStr: function (obj, keyStr) {
// convert indexes to properties
keyStr = keyStr.replace(/\[(\w+)\]/g, '.$1');
Expand All @@ -7,7 +12,7 @@ var ObjUtil = {
var aKeys = keyStr.split('.');
for (var i = 0, n = aKeys.length; i < n; ++i) {
var key = aKeys[i];
if (key in obj) {
if (ObjUtil.isObject(obj) && key in obj) {
obj = obj[key];
} else {
return;
Expand All @@ -26,7 +31,7 @@ var ObjUtil = {
if (key in obj && i + 1 < n) {
obj = obj[key];
} else if (!(key in obj) && i + 1 < n) {
obj[key] = {};
obj[key] = NumUtil.isStrNumber(aKeys[i+1]) ? [] : {};
obj = obj[key];
} else {
obj[key] = val;
Expand Down
26 changes: 26 additions & 0 deletions tests/object.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,30 @@ test('Update respective proxied locale values', () => {
let serverPayload = appObj.toJSON();
expect(serverPayload?.secondLevel?.localizations?.en?.header).toBe('englishtest');
expect(serverPayload?.secondLevel?.localizations?.fr?.header).toBe('frenchtest');
})

test('New instance setting attribute will serialize', () => {
let appObj = new AppObject();
appObj.secondLevelObj.header = 'first value';
appObj.localize('fr');
appObj.secondLevelObj.header = 'french value';
let serverPayload = appObj.toJSON();
expect(serverPayload?.secondLevel).toBeInstanceOf(Object)
expect(serverPayload?.secondLevel?.localizations?.en?.header).toBe('first value')
expect(serverPayload?.secondLevel?.localizations?.fr?.header).toBe('french value')
})

test('Serialization is symmetrical across locales even for empty values', () => {
let appObj = new AppObject();
appObj.secondLevelObj.header = 'first value';
appObj.localize('fr');
appObj.secondLevelObj.header = 'french value';
let serverPayload = appObj.toJSON();
expect(serverPayload?.secondLevel).toBeInstanceOf(Object)
expect(serverPayload?.secondLevel?.localizations?.en?.header).toBe('first value')
expect(serverPayload?.secondLevel?.localizations?.en?.subHeader).toBe('');
expect(serverPayload?.secondLevel?.localizations?.en?.description).toBe('');
expect(serverPayload?.secondLevel?.localizations?.fr?.header).toBe('french value')
expect(serverPayload?.secondLevel?.localizations?.fr?.subHeader).toBe('');
expect(serverPayload?.secondLevel?.localizations?.fr?.description).toBe('');
})
24 changes: 24 additions & 0 deletions tests/toplevel.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,28 @@ test('Update respective proxied locale values', () => {
let serverPayload = appObj.toJSON();
expect(serverPayload?.localizations?.en?.header).toBe('englishtest');
expect(serverPayload?.localizations?.fr?.header).toBe('frenchtest');
})

test('New instance setting attribute will serialize', () => {
let appObj = new AppObject();
appObj.header = 'first value';
appObj.localize('fr');
appObj.header = 'french value';
let serverPayload = appObj.toJSON();
expect(serverPayload?.localizations?.en?.header).toBe('first value')
expect(serverPayload?.localizations?.fr?.header).toBe('french value')
})

test('Serialization is symmetrical across locales even for empty values', () => {
let appObj = new AppObject();
appObj.header = 'first value';
appObj.localize('fr');
appObj.header = 'french value';
let serverPayload = appObj.toJSON();
expect(serverPayload?.localizations?.en?.header).toBe('first value');
expect(serverPayload?.localizations?.en?.subHeader).toBe('');
expect(serverPayload?.localizations?.en?.description).toBe('');
expect(serverPayload?.localizations?.fr?.header).toBe('french value');
expect(serverPayload?.localizations?.fr?.subHeader).toBe('');
expect(serverPayload?.localizations?.fr?.description).toBe('');
})