O2 launched Taro at the end of last year and has been itching to play. Considering the wX audit system, so decided to write a tool class applets. At the occasion of Taro’s 2000 issues, Natsuha has finally been launched. Source code all released (except for the private key part, GitHub has a description), the article will post some points still need to optimize, welcome to discuss together.

preface

Natsuha Weather is open source, welcome everyone to do it, give a star is also great ~ GitHub Repo

The technology stack is Taro + Mobx + TypeScript, and the interface comes from the Yahoo Weather API. Sometimes the interface fails, especially at night, and I can’t help it. 🤷

function

  • The drop-down refresh
  • Temperature switch between Fahrenheit and Celsius
  • Displays the weather forecast of the day in time
  • Show the weather forecast for the next 10 days
  • Show the current wind direction and speed
  • Display sunrise, sunset, moon phases and other information
  • Show precipitation forecast for a day
  • City weather search
  • Display retrieval records

Hit the pit

Leijiacha etc precursor

Cloud development solves the Bei problem

For well-known reasons, WX applets cannot call non-bei interfaces, even in a development environment. So we use the cloud function developed by the cloud to “reverse generation” interface, the following through an example to talk about the technical points.

Json file in the root directory: cloudfunctionRoot: functions/ Right click to create a new cloud function, let’s call it getRegion.

Since our goal is to request a non-bei interface through a cloud function, we introduced the Request-Promise library to make it easier to handle asynchronous requests.

Open the cloud function folder from your hard drive and install the dependencies:

yarn add request request-promise
Copy the code

Next we write the logic in index.js and code directly. The cloud uses the Event object to get the parameters passed from the front end, and returns the results through the Promise object. So in this case we need to get region,

// cloud function entry file const cloud = require('wx-server-sdk')
const rp = require('request-promise')

cloud.init()

exports.main = async (event, context) => {
  const region = event.region;
  const res = await rp({
    method: 'get', uri: `https://www.yahoo.com/news/_tdnews/api/resource/WeatherSearch; text=${region}`,
    json: true
  }).then((body) => {
    return {
      regionList: body
    }
  }).catch(err => {
    return err;
  })
  return res;
}
Copy the code

Taron.request () is no longer used, but wx.cloud.callFunction() is unique to cloud functions, since my current Taro version does not implement taron.cloud.callFunction (). So just start with WX.

Wx.cloud.callfunction () : wx.cloud.callfunction () :

export const httpClient = (url: string, data: any) => new Promise((resolve, reject): void => {
  wx.cloud.callFunction({
    name: url,
    data,
  }).then(res => {
    resolve(res.result);
  }).catch(e => {
    reject(e)
  });
});
Copy the code

Then we write the logic inside the store, which basically solves the data request pit.

  public getRegion = (text: string) => {
    httpClient('getRegion', {
        region: encodeURI(text),
      })
      .then((res: any) => {
        runInAction(() => {
          if(res.regionList) { this.regionList = res.regionList; }}); }) .catch(() => {setToast(toastTxt.cityFail);
      });
  };
Copy the code

🔔 Off-topic: Because the current version of taron.cloud.callFunction () is not implemented, so Lint will report an error, although it does not affect the use of, we have any good methods, can say:

Geographic information authorization issues

In this project, we need to reverse check the city information through the longitude and latitude obtained by the small program, and the small program needs user authorization to obtain the longitude and latitude. There is a pit here. When the user refuses authorization, the miniprogram’s default dialog asking for authorization does not pop up repeatedly for some time, so we have to manually direct the user to the authorization page.

The applet used to have an interface called wx.openSetting(), but TX disabled it and now only lets the user click a specific button.

I did a modal for this, and I post the key code here.

<Button openType='openSetting' onOpenSetting={() => this.onOpenSetting()}>
  OK
</Button>
Copy the code

First we must declare openType=’openSetting’ for the button so that when the user clicks it, it will be redirected to the Settings page.

Second, we need to check the user’s authorization status again when the user leaves the authorization page by clicking the back button in the upper left corner. OnOpenSetting ={() => this.onOpenSetting();

In the onOpenSetting() method, we perform the method to determine whether the user is authorized or not again. If the user is not authorized, then play modal, otherwise the corresponding data interface of the request is released.

Some tired text, directly look at the picture.

Unable to empty textbox text in the traditional way

When the user closes the search dialog, the text of the text box should be emptied, so it was initially written as follows: inputValue = “when the close button was clicked, but it didn’t work.

<Input
  type='text'
  value={inputValue}
  placeholder='Enter City or ZIP code'
  onInput={e => handleInputTextChange(e)}
/>

<Button onClick={() => hideSearchDialog()}>Close</Button>
Copy the code

We must wrap the Input and Button in a Form, add formType=’reset’ to the close Button, and add the onReset event to the Form to point to the method that closes the dialog.

<Form onReset={() => hideSearchDialog()}>
  <Input
    className={styles.input}
    type='text'
    placeholder='Enter City or ZIP code'
    onInput={e => handleInputTextChange(e)}
  />
  <Button formType='reset'>Close</Button>
</Form>;
Copy the code

Taro article

Most of them are compilation problems and webpack problems. I have put forward issues for them. If you are interested, you can follow up.

The Taro compilation ignores Spaces between templates

For example,

day-night
will compile normally, the page will see day-night normally, but if it is a variable, it will compile as day-night, notice that the space is eaten.

const day = 'day'
const night = 'night'

<Text>{day} - {night}</Text>
Copy the code

I have raised an issue #2261, but no one cares about me. If you are interested, please follow up.

Ts is not recognizedwx

Cloud (…) : Cloud (…) : Cloud (…) , so using native Wx.cloud (…) “, ts will definitely report an error.

Static files such as the CSS Module cannot be found

We initially used import to import static files, but reported “path not found”, as you can see below (but does not affect use). I raised an issue #2213, but I couldn’t solve the problem by modifying it according to the boss’s reply. I couldn’t stand all the red, so I just changed it to commonJS.

Problem

The following are some problems in the project, if you are interested, welcome to discuss.

Image loading is not friendly

The url of the interface image comes from AWS, and for well-known reasons, images often hang, so it is necessary to raise an onError event when the image dies and then give the user a hint.

Since the applet does not support new Image(), we have to use the official Image component, which fortunately supports onLoad and onError events.

The loading failure was fixed, but aws was too slow to be very friendly when loading normally (see for yourself)

Some attempts were made to load the thumbnail first and then show the full image, but the minimum size of the interface was already over 70 k, and damn Yahoo happened to encrypt the section where the image URL controls the size, so this passed.

Add a throttle to the search input box

The current practice is to add a throttle to the store constructor, but I don’t know if that makes sense.

  construtor() {
    this.getRegion = _.debounce(this.getRegion, 150);
  }
Copy the code

TODO

  • internationalization
  • Performance optimization
  • Image loading optimization
  • Jest up (initialization is done)
  • Travis CI set up (initialization set up)
  • Put the search module on a new page (force a route 😂)

The last

I will never write a small program again!