React Native - Clear Async Storage Script - node.js

I'm currently building a react native app which uses async storage. I've got conditionals within the components to decide whether to make requests to the API or use the data stored in memory. So to test out these conditionals I regularly have to clear the AsyncStorage using AsyncStorage.clear().
This works if I have it in one of the components, however it would be more practical to have it in a seperate script - which brings me to my question:
I want to have a script as below:
import AsyncStorage from '#react-native-community/async-storage';
AsyncStorage.clear();
console.log('STORAGE CLEARED');
and then run it using a command like node clearStorage.js (and later an npm script).
However I'm getting an error saying 'Cannot use import statement outside a module'.
Am I missing anything glaringly obvious/trying to do something I shouldn't? I've tried changing the file type to .mjs with no luck.

If you need to do this, you can't use a nodejs script because the node script will never get to the native side, because async-storage is a native library and it connects directly to Android or IOS.
Another solution may be at the start of the application, you can run that code, or create a Button just for dev mode and when click clean the data.
and the error 'Cannot use import statement outside a module'. it's because nodeJs don't understand the syntax import AsyncStorage from '#react-native-community/async-storage'; they need a transpiler like babel.

Related

Importing BetaAnalyticsDataClient from #google-analytics/data returns Webpack 5 errors

I am trying to create a custom dashboard on the angular app I am building. I want to use the data from Google Analytics 4 using Google Analytics Data API. I've successfully ran the scripts provided in their tutorial Using Node.JS client libraries (https://developers.google.com/analytics/devguides/reporting/data/v1/quickstart-client-libraries?hl=en_US).
I've ran the quickstart script they have provided using Node.JS and was able to get the expected response. However, when I try to ran the same script on my angular app via importing the script to fetch returned values, "ng serve" returns webpack 5 errors.
The issue was importing the BetaAnalyticsDataClient. Whenever I import it, the nodemon returns webpack errors.
The structure is like this:
simple component structure
I have a 'site-statistics.component' with its html and scss files.
I have a script named 'google-analytics.ts' inside the subfolder "services".
site-statistics.component imports an exported function from google-analytics.ts
If the issue is my usage of the Google Analytics Data API client library, I want to know how I would be able get the response from the script and send it to my angular component.
Options I've tried, but failed:
Tried adding a resolve.fallback on webpack.config.ts. However, issue still persists.
Tried setting paths to each packages on my TSCONFIG.JSON.
Tried using react-scripts-rewired
If the issue is the way I use the Google Analytics Data API client library, I want to know how I would be able get the response from the script and send it to my angular component.

Webpack with Next.js bundles file it is not supposed to in client bundle

I have a Next.js app with mongoose to connect to my mongodb. The models import db.ts to make sure that there is an active connection to the database like so:
import { model, models, Schema } from "mongoose";
import "../../db";
This is the code that connects to my database:
import mongoose from "mongoose";
mongoose.connect("mongodb://admin:admin#localhost:27022/admin");
I have gone ahead and made some serverless functions in next.js and added some database fetching from the models in my getServerSideProps. All of which worked perfectly fine. I can interact with the models, create new Documents, delete them and update them. there are no issues.
The Problem
I recently added a new component: it is at /pages/flashcards/[id].tsx. Just like my other components, this one imports one of my mongoose models. However, for some reason, Webpack feels like it should bundle the model and its import of ../../db and send it and send it over to the client, which results in this error:
TypeError: mongoose__WEBPACK_IMPORTED_MODULE_0___default(...).connect
is not a function
Again: This does not happen with any of my other components which use the exact same models as the component which is having these problems.
The issue occurs because you have the following unused import in the /pages/flashcards/[id] page.
import question from "../../db/models/question";
Any code inside getServerSideProps or getStaticProps, and imports used exclusively by these methods, is removed by Next.js when building the client bundle.
However, since question is not explicitly being used in getServerSideProps, Next.js can't figure out the import is only meant to be used on the server. This means it will be included in both the server and client bundles.
You can use the Next.js Code Elimination tool to verify what Next.js eliminates from the client-side bundle. You'll see that if you run your page's code through it, the import is not removed. However, as soon as you reference and use it inside getServerSideProps, Next.js automatically eliminates it from the imports.
Make sure to always comment out/remove unused imports (there are linting rules to help you do that).
Have you tried upgrading the next npm package to the latest version? (12.0.8 as of this writing). I had a similar issue with Next giving inconsistent errors between different API routes, all configured the same way but some raising the same TypeError you shared. Upgrading the package resolved the issue for me.

Using command line arguments with ReactJS

I'm wondering if it's possible to use command line arguments with ReactJS (not react-native). For example, is it possible to input a simple string and have it be saved as a variable so it can be displayed? The npm yargs module is the kind of thing I'm looking for, but I couldn't get that to work because the child process it spawns apparently doesn't work in a browser.
Edit: I've also tried something like including {process.argv[0]} in say an h1 tag, but nothing shows up.
React doesn't have anything special for command line arguments. In fact, it is primarily designed as a DOM library. You could use yargs and then pass the values to a React component.
For example you run this command in terminal or cmd
npm start -- foo
foo is your argument.
You can print your like this
// print process.argv
process.argv.forEach(function (val, index, array) {
console.log(index + ': ' + val);
});
in your script.
React runs is client-side
React is a client-side library. It runs in a web page, on a browser. The end-user doesn't use the command-line to "run" React, therefore command-line arguments are not available to the end-user.
For developers
As a developer, you do use tools to start a development server and launch a browser that is running React. Most likely, you're using Create React App. You can use environment variables to pass variables/arguments to React. Specifically, the documentation offers these examples:
# on Linux and macOS
REACT_APP_NOT_SECRET_CODE=abcdef npm start
# on Windows (cmd.exe)
set "REACT_APP_NOT_SECRET_CODE=abcdef" && npm start
Note that these variables are embedded into React at build time, when Create React App bundles and builds your app (kind of like compiling). This means that if you build your React project and then transfer the output files to another server and try to pass new variables, nothing will change.
For servers
If your React build files are on a server and you want to be able to pass command-line arguments to the server and have React change, this is also possible, but largely depends on what software you are using to serve. Broadly, the server would take the runtime argument and pass it into the template which renders your React app. Then any Javascript that runs on that page can access the arguments.

nwjs reactjs, confused about my context. Document is undefined

In my nwjs application i am using React to build my UI. Currently, React is being loaded via a <script> tag in the main file, index.html. index.html has another <script> tag which loads main.js containing code which defines and renders my React components as well as requiring (require()) a few Node modules such as "fs" and "McFly".
This all seems to be working, however when i try using another node module (react-inlinesvg) i get an error, "document is undefined".
Having looked online for help, i have come to the conclusion that React now believes that it is being run on the server? Which is odd, as before i started using the react-inlinesvg module it was happily rendering components using React.render (clientside rendering).
If you need any more context or information then please ask.
It could be that you are rendering on the server side, or also that you are rendering both sides. In the second case you could simple nest the line that is causing you error with:
if (process.env.BROWSER) {
the line causing the error
}
If the error disappears, it means that you are on the server side also!
I hope this helps...
Basically if you code is universal (or isomorphic, if you want...) with this check you can execute the code only on client side, you want to do this to use a particular style-sheet for example:
if (process.env.BROWSER) {
require("../style/main.scss");
}
Naturally if you want to do stuff server-side you can check
if (!process.env.BROWSER) {
}
if any one face this he can solve it in 2 ways:
Solution 1: if you are using nw.js 15 or above try to enable mix context mode:
in your package.json add this flag:
"chromium-args": "--mixed-context"
Solution 2: expose document to the global object using this hack:
global.document = window.document;

Meteor.js: How do you require or link one javascript file in another on the client and the server?

1) In node on the backend to link one javascript file to another we use the require statement and module.exports.
This allows us to create modules of code and link them together.
How do the same thing in Meteor?
2) On the front end, in Meteor is I want to access a code from another front end javascript file, I have to use globals. Is there a better way to do this, so I can require one javascript file in another file? I think something like browserify does this but I am not sure how to integrate this with Meteor.
Basically if on the client I have one file
browserifyTest.coffee
test = () ->
alert 'Hello'
I want to be able to access this test function in another file
test.coffee
Template.profileEdit.rendered = ->
$ ->
setPaddingIfMenuOpen()
test()
How can I do this in Meteor without using globals?
Meteor wraps all the code in a module (function(){...your code...})() for every file we create. If you want to export something out of your js file (module), make it a global. i.e don't use var with the variable name you want to export and it'll be accessible in all files which get included after this module. Keep in mind the order in which meteor includes js files http://docs.meteor.com/#structuringyourapp
I don't think you can do this without using globals. Meteor wraps code in js files in SEF (self executing function) expressions, and exports api is available for packages only. What problem do you exactly have with globals? I've worked with fairly large Meteor projects and while using a global object to keep my global helpers namespaces, I never had any issues with this approach of accessing functions/data from one file in other files.
You can use a local package, which is just like a normal Meteor package but used only in your app.
If the package proves to be useful in other apps, you may even publish it on atmosphere.
I suggest you read the WIP section "Writing Packages" of the Meteor docs, but expect breaking changes in coming weeks as Meteor 0.9 will include the final Package API, which is going to be slightly different.
http://docs.meteor.com/#writingpackages
Basically, you need to create a package directory (my-package) and put it under /packages.
Then you need a package description file which needs to be named package.js at the root of your package.
/packages/my-package/package.js
Package.describe({
summary:"Provides test"
});
Package.on_use(function(api){
api.use(["underscore","jquery"],"client");
api.add_files("client/lib/test.js","client");
// api.export is what you've been looking for all along !
api.export("Test","client");
});
Usually I try to mimic the Meteor application structure in my package so that's why I'd put test.js under my-package/client/lib/test.js : it's a utility function residing in the client.
/packages/my-package/client/lib/test.js
Test={
test:function(){
alert("Hello !");
}
};
Another package convention is to declare a package-global object containing everything public and then exporting this single object so the app can access it.
The variables you export NEED to be package-global so don't forget to remove the var keyword when declaring them : package scope is just like regular meteor app scope.
Last but not least, don't forget to meteor add your package :
meteor add my-package
And you will be able to use Test.test in the client without polluting the global namespace.
EDIT due to second question posted in the comments.
Suppose now you want to use NPM modules in your package.
I'll use momentjs as an example because it's simple yet interesting enough.
First you need to call Npm.depends in package.js, we'll depend on the latest version of momentjs :
/packages/my-moment-package/package.js
Package.describe({
summary:"Yet another moment packaged for Meteor"
});
Npm.depends({
"moment":"2.7.0"
});
Package.on_use(function(api){
api.add_files("server/lib/moment.js");
api.export("moment","server");
});
Then you can use Npm.require in your server side code just like this :
/packages/my-moment-package/server/moment.js
moment=Npm.require("moment");
A real moment package would also export moment in the client by loading the client side version of momentjs.
You can use the atmosphere npm package http://atmospherejs.com/package/npm which lets you use directly NPM packages in your server code without the need of wrapping them in a Meteor package first.
Of course if a specific NPM package has been converted to Meteor and is well supported on atmosphere you should use it.

Resources