Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: [Angular] fix logic used for parsing objects provided as input to useObjectWrapper #1490

Merged
merged 17 commits into from
Aug 26, 2024

Conversation

lukjab71
Copy link
Contributor

@lukjab71 lukjab71 commented Jul 5, 2024

Description

This is propsed fix to issue: 1410

  • What changes you made:
    The logic responsible for parsing an input to the method was incorrect. It used ',' comma as object separator. This gave weird results for any other constructs that would use comma, like arrays. Besides, this logic should probably be used only when input actually has spread operator in it.

Regardless from object detection logic, I'm not convinced if logic responsible for concatenation ${spreadOutObjects.join(', ')}, ${otherObjs.join(', ')} was correct. spreadOutObjects collects objects that use spread operator. otherObjs collect the rest of the objects from input. When we concatenate them using the initial logic, I believe we are completely mixing the order of objects, as there is no guarantee that spreadOutObjects in the original input, where at the begining. What if they were spread out somewhere else, in some nested object, of some complicated input? I believe this would either completely malform the object or in best case change the object structure.

Now, about the propsed solution. As I understand, the whole purpose of this method is to get rid of ... spread operator from syntax, as angular won't accept it.

I tried to approach this problem in recursive way(to fix initial way of detecting objects - instead of using comma as object separator, try to figure start bracket and end bracket), but it is tricky, as regex are not good with recursive problems and even when I extracted recursion to separate method, it still was tricky for some complicated examples. And then I switched the approach - in the end, why do we need to detect separate objects? Our goal is to get rid of ... from the string. So we can simply get rid of the ... and then deal with potential consequences:

  1. someField: ...someObject -> remove ... and we are done
  2. someField: {...someObject} -> remove ... and we are left with {object} result
  3. someField: {...{nestedDeeper: true }} -> remove ... and we are left with {{ something: true }} result

I believe those cases will cover every possible variations on different levels of nesting. So after removing ... we just have to cleanup what's left.

I prepared the PR using remarks from CONTRIBUTING.md file, however, I noticed that even without my changes there are tests failing in the core package(?).

@lukjab71 lukjab71 requested a review from samijaber as a code owner July 5, 2024 06:42
Copy link

changeset-bot bot commented Jul 5, 2024

🦋 Changeset detected

Latest commit: c5e5b77

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@builder.io/mitosis Patch
@builder.io/mitosis-cli Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

nx-cloud bot commented Jul 31, 2024

☁️ Nx Cloud Report

CI is running/has finished running commands for commit c5e5b77. As they complete they will appear below. Click to see the status, the terminal output, and the build insights.

📂 See all runs for this CI Pipeline Execution


✅ Successfully ran 4 targets

Sent with 💌 from NxCloud.

return (
<div>
<CustomComponent
tooltipPlacementOptions={{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lukjab71 thanks for the PR! just wanted to understand how this will handle spread values, can you please add a test for that? As far as I understand this will just remove ... from any values and let useObjectWrapper handle it right?

you can use this for test:

import { useStore } from "@builder.io/mitosis";

export default function MyComponent(props) {
  const state = useStore({
    attributes: {id:1},
    attributes2: {id2:1},
    something: {id3:1},
  });

  return (
    <div>
      <Comp
        val1={{...state.attributes2}}
        val2={{
          ...state.attributes,
          ...state.attributes2,
        }}
        val3={{
          ...state.something,
         anything: 'hello',
          hello: 'world', 
        }}
        val4={{
          ...state.attributes,
          ...state.something,
          anything: [1,2,3],
          hello: 'hello',
          ...state.attributes2,
        }}
        val5={{
          ...state.attributes,
          ...state.something,
          anything: [1,2,3],
          hello: 'hello',
          ...props.spreadAttrs,
        }}
        />
    </div>
  );
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is how I understood the initial logic for useObjectWrapper, that had the bug. Remove spread operator to input parameter, provided to useObjectWrapper function, to avoid using spread syntax for angular components inputs.

I updated the raw file and snaps with propsed example.

To be honest I don't fully understand the testing strategy in the repo. Even without my changes, when I run test command for core package I get:

Test Files 5 failed | 37 passed | 1 skipped (43)
Tests 48 failed | 5914 passed | 3 skipped (5965)

Those failures are completely unrelated to my changes. I hope that in general everything is working as expected.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for explaining, looks good to me!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please try to pull the latest main and run yarn test:update from root and see if it works?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might have to lint the test file too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've merged with current main branch, I've run yarn test:update. It went through with success. I used prettier and lint command.

Lukasz.Jablonski added 5 commits August 2, 2024 09:36
…pper-1410

# Conflicts:
#	packages/core/src/__tests__/test-generator.ts
…pper-1410

# Conflicts:
#	packages/core/src/__tests__/test-generator.ts
@@ -2300,7 +2291,14 @@ import { Component, Input } from \\"@angular/core\\";
template: \`
<video
preload=\\"none\\"
[ngStyle]=\\"useObjectWrapper(attributes?.style, { width: '100%' }, { height: '100%' }, { objectFit: fit }, { objectPosition: position }, { borderRadius: 1 })\\"
[ngStyle]=\\"useObjectWrapper(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im curious if this will actually work? this should fail right? because we cannot send params like this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good remark. My solution was too generic and it messed up the parameters. I updated it. It reuses both concepts - initial and mine.

Spread operator is removed. If the object was presented in form of {...obj}, we replace it with obj. If there was some spread inside of object, we get rid of spread and deal with consequences. {...obj1,test:true, ...obj2} => obj1, {test: true}, obj2.

When I look at generated snaps, they seem to be ok.

)\\"
[val5]=\\"useObjectWrapper( attributes,
something,
anything: [1, 2, 3],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same thing here, will we be able to pass params like this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good remark. My solution was too generic and it messed up the parameters. I updated it. It reuses both concepts - initial and mine.

Spread operator is removed. If the object was presented in form of {...obj}, we replace it with obj. If there was some spread inside of object, we get rid of spread and deal with consequences. {...obj1,test:true, ...obj2} => obj1, {test: true}, obj2.

When I look at generated snaps, they seem to be ok.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks awesome!

Comment on lines 129 to 131
temp = temp.replace(/\{\s*\.\.\.(\w+)\s*}/g, '$1');
temp = temp.replace(/\.\.\./g, '');
temp = temp.replace(/(\s*\w+\s*:\s*((["'].+["'])|(\[.+])|([\w.]+)))(,|[\n\s]*)/g, `{ $1 },`);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please add some comments for each regex, explaining the purpose behind it for future reference?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ofc, I added comments for each step of this operation in 801cf8bf57

Copy link
Collaborator

@sidmohanty11 sidmohanty11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thank you very much for your contribution @lukjab71!

@sidmohanty11 sidmohanty11 requested review from samijaber and removed request for samijaber August 22, 2024 14:25
@samijaber samijaber merged commit d446881 into BuilderIO:main Aug 26, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants