0

I mistakenly thought I would need to proxy the array as nested but I was incorrect. The correct answer was just a simple array utilizing get() to proxy the array and all it's content.

I have a site that gets data through a function that creates an array. The problem is that array is nested whenever it gets to the site. This isn't an issue for the site since it can use that nested array to create a table. However, I'm trying to set up a proxy to monitor that array so that whenever something changes in the array on the backend, the site table will update.

The array pulls more data than I am showing here but this is what the array looks like:

//each table has a checkbox column
{    
'0' : {
    'Service': 'On Site',
    'Authorization': '4/15/22',
    'Client Waiver Due' : '4/15/22',
    '90 Day Progress' : '1' //checked
},
'1' : {
    'Service': 'Off Site',
    'Authorization': '7/15/22',
    'Client Waiver Due' : '7/15/22'
    '90 Day Progress' : '0' //unchecked
},

I'm trying to proxy the Service, Authorization, Client Waiver Due and 90 Day Progress every time there is a change on the backend. I'm fairly new to programming so I apologize if the answer is simpler than I think it is.

I tried the answer provided on in the question How to use javascript proxy for nested objects but I keep getting undefined or some error is spat out in the console.

I think it might be relevant so I should mention that each value will be capitalized and some will have spaces in them so proxy.0.Service and proxy.0.Client Waiver Due are most likely part of the issue I am having.

edit: Here is what the code looks like that throws errors.

const handler = {
  get(target, key) {
    if (key == 'isProxy')
      return true;

    const prop = target[key];

    // return if property not found
    if (typeof prop == 'undefined')
      return;

    // set value as proxy if object
    if (!prop.isProxy && typeof prop === 'object')
      target[key] = new Proxy(prop, handler);

    return target[key];
  },
  set(target, key, value) {
    console.log('Setting', target, `.${key} to equal`, value);

    // todo : call callback

    target[key] = value;
    return true;
  }
};

const test =[
         { Client: 'Jon Doe',
           Service: 'Off Site',
           '90 Day Review': '6/13/22',
           'Day Review Completed?': '1' },
         { Client: 'Jane Smith',
           Service: 'On Site',
           '90 Day Review': '7/11/22',
           'Day Review Completed?': '0' } 
            ]
    

    const proxy = new Proxy(test, handler);

    console.log(proxy);
    console.log(proxy.string); // "data"

    proxy.string = "Hello";

    console.log(proxy.string); // "Hello"

    console.log(proxy.object); // { "string": "data", "number": 32434 }

    proxy.object.string = "World";

    console.log(proxy.object.string); // "World"
UmaLPZ
  • 69
  • 6
  • Please show us the code you tried - how did you create the proxy, how did you use it, what errors did you get? – Bergi Jul 23 '22 at 21:49
  • @Bergi Pretty much the code that is in the other question I linked except the array. I'll edit the original post to show you. – UmaLPZ Jul 24 '22 at 00:47
  • 1
    `test` is not an array. It's a plain object. Note that it doesn't have a `length` property. If you want to test with an actual array, use array semantics, i.e., `const test = [{ 'Service': 'On Site', ... }, { 'Service': 'Off Site', ... }];` – Heretic Monkey Jul 24 '22 at 01:02
  • 1
    When I run that code, I get a syntax error from the unmatched braces of the object literal. Which, also, is not exactly creating an array… – Bergi Jul 24 '22 at 01:08
  • @Bergi So the array comes from a function and I trimmed it down so I didn't take up half the post. The array the function creates is in the format that you are refereeing to. I'll try to edit it again. – UmaLPZ Jul 24 '22 at 01:32
  • Thanks for the update. You claim in the code that `console.log(proxy.string);` logs `"data"`, and that `console.log(proxy.object);` logs `{ "string": "data", "number": 32434 }`, but neither of those is true when you look at the the output. You've got a proxy over an array, which has neither `.string` nor `.data` properties, so why do you expect to get anything else than `undefined` when accessing them? – Bergi Jul 24 '22 at 12:06
  • @Bergi Yeah that was my bad haha. I forgot to change what I pasted here to match what I actually had in my code. I forgot to change `string` to `Client` for example. I also thought the array was different because of how it was generated by a function and then appeared on the console. Turns out it was just a simple array that I could proxy using `get()`. Thank you for all the help! – UmaLPZ Jul 24 '22 at 19:41
  • Still it's not `proxy.Client`, but `proxy[0].Client` or `proxy[1].Client`?! – Bergi Jul 24 '22 at 20:27

1 Answers1

-1

Ok well I feel dumb :/ I assumed that because it was an array that was created by a function and displayed on the console as

'0' : {
    'Service': 'On Site',
    'Authorization': '4/15/22',
    'Client Waiver Due' : '4/15/22',
    '90 Day Progress' : '1' 
},

that I would need to proxy it as a nested array. I was wrong... Turns out all I needed to do was make a simple, straightforward proxy.

const records = new Proxy(
    [
        { Client: "Jon Doe", Service: "Off Site", Authorization: "6/13/22" },
        { Client: "Jane Smith", Service: "Off Site", Authorization: "7/11/22" },
    ],
    {
        get(obj, prop) {
            if (prop in obj) {
                return obj[prop];
            }
            return undefined;
        },
    }
);

console.log(records);

Thank you to Bergi and Heretic Monkey for explaining everything to me. Now to figure out the rest of this project!

edit: Still haven't figured it out it seems :/

UmaLPZ
  • 69
  • 6
  • This traps accesses like `records[0]`, `records[1]` or `records.length`, but not accesses to `.Client` or `.Service` or `.Authorization` on the objects in the array. The OP appears to want to trap those nested accesses as well. – Bergi Jul 24 '22 at 20:29
  • @Bergi oh you are right. So I can proxy it if I do `records[0].Client`, or `records[1].Client`, but how would I proxy them all without having to do `records[0]`, `records[1]`, `records[2]`, ... – UmaLPZ Jul 25 '22 at 02:34
  • Use the (working!) `handler` from the question – Bergi Jul 25 '22 at 03:06