Closed Triggs9 closed 3 years ago
Thank you for filing this issue. In order for us to investigate this issue, please provide a minimal project (ideally a GitHub repo) that illustrates the problem.
not to keen to release my source code, and for me to built a repro repo for something this small would take to long. I assume its because this file: https://github.com/aspnet/AspNetCore/blob/master/src/Components/Web.JS/src/Rendering/ElementReferenceCapture.ts isn't being applied to objects being returned from c# calls, not sure exactly where yet, ill keep looking.
this is where the dotnet object is returned, but its as a json object, is it still possible to apply the above method (getElementByCaptureId) to that json?
Here is my crude implementation that suites my needs for now:
export function BlazorIDToElement(incomingObject: any): OriComponent
{
let elementRefKey = '__internalId';
//https://stackoverflow.com/questions/18936915/dynamically-set-property-of-nested-object
let setValue = (path: string, value: Element | null) => {
var schema = incomingObject; // a moving reference to internal objects within obj
var pList = path.split('.');
var len = pList.length;
for(var i = 0; i < len-1; i++) {
var elem = pList[i];
if( !schema[elem] ) schema[elem] = {}
schema = schema[elem];
}
schema[pList[len-1]] = value;
};
//https://stackoverflow.com/questions/15690706/recursively-looping-through-an-object-to-build-a-property-list
let iterateObject = (obj: any, stack: string | null = null): any => {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
if(stack === null) stack = property
else stack = stack + "." + property
iterateObject(obj[property], stack);
} else {
console.log("Current property: ")
console.log(property)
console.log((property === elementRefKey))
console.log(typeof obj[property] === 'string')
if((property === elementRefKey) && typeof obj[property] === 'string')
{
if(stack !== null)
setValue(stack, getElementByCaptureId(obj[property]))
//console.log(getElementByCaptureId(obj[property]))
}
console.log(incomingObject)
console.log(stack)
}
}
}
};
iterateObject(incomingObject);
return incomingObject;
}
@Triggs9 it's still not very clear what scenario it is that you're attempting to solve. It would help to share a minimal repro that exhibits what it is that's problematic for us to investigate this further.
I refuse to create a repo for some who refuses to read and even slightly attempt to understand the bug being reported and implements a blanket "i need this to do my job" as a machine/robot would. I have even gone to the extent of solving the bug for you. don't comment on this thread again please.
You shouldn't pass an ElementReference to JS and then pass it back, because by the time the JS calls C# the element may have been re-rendered and have a new ID.
What do you want to achieve?
So the ElementReference is always being generated by CS code, and passed to JS, the means by which its being passed are changing.
One is through a JS parameter: TS Method
public RecieveComponent(component: object)
{
let NewComponent = component
}
invoked in CSharp with:
this._currentJSRuntime.InvokeVoidAsync("RecieveComponent", newComponent);
the other is through the DotNet Interop Object and a return value from that CS Method call CSharp Method
public object RecieveNewComponent(component: object)
invoked in TypeScript with:
let NewComponent = this._dotNetInterop.invokeMethodAsync("RecieveNewComponent");
the latter call made in typescript fails to resolve the id to the actual html tag, while the first call does not. the exact same object represented in C# is used for both calls, again always originating from CS
when your blazor engine returns the js object, as the result of the returned C# object, its not being checked for elementreferences
You aren't supposed to pass element references from javascript to C#. They should only be passed the other way, so javascript can perform an operation immediately and then discard the reference.
Can you tell me your goal, in case there is a better way to do what you want?
I am not, as stated above: "the ElementReference is always being generated by CS code, and passed to JS". I might create a reproduction repo if i get time, but as stated above also: "Here is my crude implementation that suites my needs for now"
I'm sorry but I agree with @pranavkm that your issue needs more information.
I'm struggling to work out exactly what you are trying to do, snippets of failing code aren't helping, and a long complex JS function that solves the problem doesn't help to clear it up.
Please submit a very minimal project.
@Triggs9 People here are trying to help you, but your being very abrasive and in no way attempting to help us to help you, we can see what your trying to ask, but your not answering the questions being asked by others, and thus we can't help you.
As @mrpmorris states there are MANY ways of doing what your trying to achieve, and if you explain your goals, then we might be able to tell you a BETTER way to do what your trying to do.
If you don't explain, then there's little we can do to help, other than WAIT until what you describe as a bug to be investigated, and that's simply not going to happen overnight.
If you want to try to reach a solution now, then help us... to help you!
Ok I've read through this several times now and it appears that what your trying to do is pass in an existing HTML elements ID, then get a list of all it's properties back to your C# code in something like a Dictionary<string, object>
But... your trying to do this in an async and/or call back way, EG: make the call, then a short while later get a "callback" with the data in that you expect.
Correct?
Created a reproduction repo here:
https://github.com/Triggs9/BlazorElementReferenceBug
it has alot of code i have been working on for a while now, so i copyright it as much as positing something publicly on github will allow ha ha, but in any case there are three variables if you open the web browser console and type in: WorkingThroughJSParam WorkingComponent FailedComponent
WorkingThroughJSParam:
WorkingComponent:
FailedComponent:
the TextTag parameter should result in a JS Element, not just a string ID of the element for all 3 objects
my proposal for a fix, is that the object is always handled by the same handler in C# whether as a returned object or passed to js as a parameter
let me know if you need more information
an npm install
command as well as a npm run script build:dev
is required before running dotnet run
I don't have time to look now, it's getting very late here in the UK, but I'm sure others will get a look in before I get chance tomorrow.
Was I correct in my last comment about what I thought you where trying to achieve?
no, its all one way right now all C# to JS, the interop can work as two entities, DotNetIntrop in JS and JSInterop in C# and still pass data one way, or both if desired. This one is Entirely C# to JS one way, no returned data to C#.
I can see where alot of C# guys get confused, and assume that i want everything done in C#. But JS has alot of animation libraries like GSAP. That C# could probably never provide purely due to its complexity involved with typing everything. I want the elements in TS so i can handle the visual side of things in typescript, i want C# to handle the actual data structure of my components as thats what it does better than C#. Thats the goal atleast.
I've not had chance to follow up on this yet... "work explosion" dunno if anyone else has though.
Thank you for contacting us. Due to a lack of activity on this discussion issue we're closing it in an effort to keep our backlog clean. If you believe there is a concern related to the ASP.NET Core framework, which hasn't been addressed yet, please file a new issue.
This issue will be locked after 30 more days of inactivity. If you still wish to discuss this subject after then, please create a new issue!
Describe the bug
when calling a C# call from JS the returned object fails to resolve ElementReference to a referenced element. C# calling JS with the same object resolves the element reference correctly.
they are both resolving to JSObjects some how, just wondering if its possible for the returned object to be resolved as an ElementReference?
this is currently a blocker for me because i can't simply return the same object requested, id have to have a js callback, that i am unsure of how to implement correctly.
EDIT: Just figured out a callback solution here: https://stackoverflow.com/questions/56627649/how-can-i-get-javascript-callback-in-net-blazor
but this bug would be more simple.
To Reproduce
Failed TypeScript ElementReference Resolution code:
Output of failed: typeof: object __internalId: "50c7d062-116e-4f5b-afbd-dba94f3521f2"
Working TypeScript ElementReference Resolution code
Output of working: \New Font\
_dotNetInterop is defined as:
C#:
Got Exceptions? Include both the message and the stack trace -->
Further technical details
dotnet --info
dotnet --info .NET Core SDK (reflecting any global.json): Version: 3.0.100 Commit: 04339c3a26Runtime Environment: OS Name: Windows OS Version: 10.0.18362 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\3.0.100\
Host (useful for support): Version: 3.0.0 Commit: 7d57652f33
.NET Core SDKs installed: 2.2.402 [C:\Program Files\dotnet\sdk] 3.0.100 [C:\Program Files\dotnet\sdk]
.NET Core runtimes installed: Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.All 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 2.2.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
To install additional .NET Core runtimes or SDKs: https://aka.ms/dotnet-download