Context
I'm trying to debug a React application but cannot modify the source code to log redux variables. In chrome I'm able to access the redux store via the associated extension but it seems no such equivalent exists for safari.
Question
How can I access the redux store in Safari? Can I do so using the console?
The simplest solution, unfortunately, is to modify the source code to set a global variable to the Redux store. (It may be worth preemptively modifying any applications you can control to do this, just to make Safari easier to debug.)
Without modifying the source code, it should be possible, although it's awkward. The following instructions work for React 16.12.0.
In Safari's Web Inspector (dev tools), go to the Elements tab and find your React root element (the <div id="root"> or similar that you pass to ReactDOM.render).
Click on it. Web Inspector should show a = $0 next to it, indicating that you can now reference that DOM node in the Web Inspector console as $0.
In the Web Inspector's Console tab, type Object.keys($0) and press Enter to see the internal properties that React adds to the DOM node. For my app, I see ["__reactContainere$8yexuoe6iiv", "_reactRootContainer"].
Dump the internal React object to the console by typing $0["__reactContainere$8yexuoe6iiv"] (substituting your internal property name) and pressing Enter.
Inspect the object properties to find the Redux store: on my app, it's under child, under memoizedProps, under store, but this may depend on the specifics of your React component hierarchy and where and how you mount Redux's <Provider>.
Use the store reference you just found to call Redux's getState. For my app, that means typing $0["__reactContainere$8yexuoe6iiv"].child.memoizedProps.store.getState() and pressing Enter.
A simpler one-line alternative to the above:
document.getElementById('root')['_reactRootContainer']._internalRoot.current.child.memoizedProps.store.getState()
In case you are using Nextjs framework, you can achieve this by opening the console in safari. Type window in it. Expand it. Now just check in the window object property. You will find a key something like '__REDUX' or something like that. In my case it was __NEXT_REDUX_STORE__.
Now after you find it just enter the following in your console.:
__NEXT_REDUX_STORE__.getState();
you can now check your current redux state of your application.
I'm not aware of a safari extension for redux debugging (corrections welcome). This thread suggests that it's due to a lack of a dev-tools API: https://github.com/zalmoxisus/redux-devtools-extension/issues/435
Redux state isn't in the global scope, so you won't be able to access it through the console without modifying the source code.
You could just extract state using the connect function. Then just stringify it?
<pre>JSON.stringify({this.props.store, null, 2})</pre>
Then you could visually see it.
Adding to #josh-kelley's answer...
In 2021, tested with Safari Version 12.1 (14607.1.40.1.4), following line did the trick for me:
document.getElementById('root')['_reactRootContainer']
._internalRoot.current.child.memoizedProps
.children.props.store.getState()
Notice the children.props difference from what #josh had mentioned.
According to its GitHub repository for other browsers use remote-redux-devtools.
Related
I have a problem when debugging React on initial page load. As you can see from the screenshot, if I hover over this I can see the content but if I use console it says that this is undefined. This only happens when I reload the page, if I debug when clicking around this problem does not occur. I have React Developer Tools for Chrome installed and noted that when this is happening it only says Connecting to React…. Could this be the problem?
https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en
I'm using .tsx files (.jsx but with TypeScript) if that could matter.
Sources tab:
React tab:
Based on your updated comments, if you launch your function from the constructor and then stop it with a breakpoint, the constructor won't finish executing, which means it won't be able to correctly set the prototype chain and most important, set the correct reference to this.
I'm trying to explore a jquery plugin.
var fb = new FormBuilder();
$(#fb).someMethod();
console.log($(fb)) How can I list all the functions/methods that I can use here?
Off the top of my head, here are the options you have:
1- Check the plugins' documentation. This is my prefer option because exploring the list of functions and methods DON"T necessarily describe the object's behaviour. However, documentation usually does
2- If the plugin is open source, then explore the internals by yourself
3- dump the object to the console using console.log. IMO, Google Chrome has one of the best (if not the best) developer tools integrated to the browser
4- Similar to the above you can add a breakpoint or a debugger statement to pause execution of javascript wherever you want and then explore the object in question
Below is a screenshot example of Chrome's Dev tools where I placed a breakpoint somewhere on this Stackoverflow page. You can see the StackExchange's object definition
I'm attempting to track some actions on a webpage that requires me setting a value in the datalayer.
I'd like to do the casperjs/phantom equivilant to this...
dataLayer.push({test: "boom"});
Directly into the web browser's console. This works manually.
It's been a while since I've used casper/phantom so closely. Im currently trying the following...
this.evaluate('console.log(\'dataLayer.push({test: "boom"});\'); console.log("dataLayer");');
Is there a way to achieve my goal?
Also, bonus 'highfive' to anyone who can also allow me to follow this up by accessing the datalayer to verify its been set.
--Edit--
I am also currently launching the runs with options...
--ssl-protocol=any --web-security=no
Using Ember debug Chrome extension, I have identified this component in a website I am trying to automate (but do not have direct access to change the code):
<MYAPP#component:zipcode-field::ember592>
Which is shown in hierarchy as:
application
engine
myui
zipcodeField
If I edit the value property of that element in the debugger, it updates the UI and model as desired. Can I do this via a one-liner from the console?
Update: So far, I am able to enter this in the console:
Ember.lookup.$E.container.lookup("MYAPP#component:zipcode-field")
But unable to access/alter its value property as in the debugger.
Update:
In feedback to one of the answers, my aim is to have a console one-liner, which could be given to someone without any debuggers installed in order to run the code with the same behaviour. Using a variable such as $E within the console requires that the element has been manually selected prior to running the code, which would not be sufficient.
Correct me if I am wrong but it seems that you aren't using the ember inspector (available on firefox and as a bookmarklet).
Once you have that installed it is really easy to inspect debug and modify anything ember related, for the purpose of this answer I will be using the chrome version.
Open up your chrome dev tools in the tab that has your ember app running,
once there head to the ember tab in the developer tools.
In order to see the components you will have to tick a checkbox
Once enabled you will be able to see all of the components currently used.
Clicking on a component will open up a panel that contains all of the component's properties.
In order to access those properties from the console all you need to do is click on the $E next to the components.
Once clicked you should see something similar in the console.
Ember Inspector ($E): Class {helperName: (...), logout: (...), isOpenBinding: StreamBinding, currentUserBinding: StreamBinding, _morph: Morph…}
Now all you need to do in order to get the property values:
$E.get('myProperty');
And To set them:
$E.set('myProperty', newValue);
A component is just a view, so the following should work:
Ember.View.views[<GUID>]
So in your example:
Ember.View.views['ember592']
You need to use get/set if you want to modify/read the value property, for example:
Ember.View.views['ember592'].get('value')
Ember.View.views['ember592'].set('value', 'newValue')
Found a gist that works with Ember 2.13
App.__container__.lookup('-view-registry:main')[componentId]; // componentId i.e. "ember4322"
Credit goes to ngyv: https://gist.github.com/ngyv/819e2cc78eca2a3b19599707e1461205
I am trying to over ride one the notification popups of browser using the following code:
var branch = Components.classes["#mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
But in Mozilla Firefox, I get the error Component.classes is undefined.
And in Chrome Browser, I get the error Component is undefined.
Well I have realised I need to include something in my website. But I am unable to find exactly what is required.
Please anybody help. I googled about it a lot, but I have never used this thing before(the Classes) and I am unable to search what will help me out. i dont even have any idea that what will be the tags for this thing. I have never used Component or its classes
My website is in ZF2.
Components Object is non-standard feature. See https://developer.mozilla.org/en/docs/Components_object.
It also says
Warning: This object is only intended for code running with chrome
privileges. Exposing the object to regular web code was a mistake.