Size: a a a

JavaScript.Ninja

2020 September 01

R

Remite in JavaScript.Ninja
El Nasurov
Подскажите, пожалуйста, может ли поле data в объекте api ответа (использую axios) быть null или undefined ?

Кейс:
Делаю проверку контрактов и хочется знать, нужло ли всегда проверять data на null/undefined, типа такого:

const { data } = await Axios.get();
if (data && data.avatar) {
 ответ норм, продолжаем
}

вот тут, нужно ли проверять data на null/undef ? (ибо если напишу просто if (data.avatar), а data окажется null/undef то будет ошибка - нельзя прочитать свойство avatar у undef/null)
Вы кстати можете использовать значения по умолчанию в деструктуризации

const { data = {} } = await Axios.get();


и тогда не надо будет проверять :)
источник

EN

El Nasurov in JavaScript.Ninja
Remite
Вы кстати можете использовать значения по умолчанию в деструктуризации

const { data = {} } = await Axios.get();


и тогда не надо будет проверять :)
Кстати да
источник

IK

Illya Klymov in JavaScript.Ninja
Remite
Вы кстати можете использовать значения по умолчанию в деструктуризации

const { data = {} } = await Axios.get();


и тогда не надо будет проверять :)
Это не сработает если data null
источник

R

Remite in JavaScript.Ninja
действительно :(
источник

IK

Illya Klymov in JavaScript.Ninja
Проще написать data?.avatar и не думать
источник

МВ

Мопсим Вертухаев... in JavaScript.Ninja
const { data } = await Axios.get()
.catch(() => ({}))
источник

IK

Illya Klymov in JavaScript.Ninja
Мопсим Вертухаев
const { data } = await Axios.get()
.catch(() => ({}))
Вот так точно не надо. Глотать ошибки плохо
источник

AC

Alexander Chernobai in JavaScript.Ninja
разве-что еще возможно бабель донастроить на .?
источник

EN

El Nasurov in JavaScript.Ninja
Illya Klymov
Проще написать data?.avatar и не думать
Круто, открыл для себя новый синтаксис.

Давно это поддерживается? Сейчас попробовал в консоли бразуера, отлично работает.

Можно всякие длинные цепочки составлять, типа:

if (obj?.property?.property?.property)

вместо

if (obj && obj.property &&  obj.property.property &&  obj.property.property.property)
источник

V

Vladosik in JavaScript.Ninja
Могу ли я создать новую переменную в объекте после его инициализации?
в моем случае есть массив объектов, в котором каждому объекту надо создать поле id, которое будет инкрементиться
источник

v

vasilich in JavaScript.Ninja
Vladosik
Могу ли я создать новую переменную в объекте после его инициализации?
в моем случае есть массив объектов, в котором каждому объекту надо создать поле id, которое будет инкрементиться
Можешь
источник

V

Vladosik in JavaScript.Ninja
просто перебрать массив и добавить поле со значением каждому объекту?
источник

R

Remite in JavaScript.Ninja
El Nasurov
Круто, открыл для себя новый синтаксис.

Давно это поддерживается? Сейчас попробовал в консоли бразуера, отлично работает.

Можно всякие длинные цепочки составлять, типа:

if (obj?.property?.property?.property)

вместо

if (obj && obj.property &&  obj.property.property &&  obj.property.property.property)
источник

Б

Богдан in JavaScript.Ninja
Illya Klymov
с mobx когда данные лежат в пачке разных сторов это очень больно было
А может не нужно было хранить в пачке разных сторов? Поделюсь подходом который применяю я - у меня в mobx состояния приложения хранится в одном единственном объекте (как в redux) и в то же время это граф отдельных сторов (в том смысле что каждый компонент может работать с ним как с локальным стором)
Cостояние любого приложения на mobx я храню в единственном глобальном объекте у которого есть поле с ссылкой на объект юзера а дальше состояние организуется подобно схемы в базе данных (one-to-many это поле с массивом объектов, many-to-many это через промежуточные объекты).
Пример - есть приложение в котором юзер может создавать папки, в папках -проекты, в проектах - задачи а в задачах комментарии. Состояние такого приложения на mobx я храню в одном единственном объекте AppState
const AppState = {
theme: `...`,
locale: `...`,
user: {
 id: `...`
 firstName: `...`,
 lastName: `...`,
 folders: [
  {
   id: `...`
   name: `folder1`,
   projects: [
    {
     id: `..`,
     name: `project1`,
     tasks: [
      {
       id: ``,
       text: `..`,
       comments: [
         {id: `..`, text: `...`},
         ....
       ]
      },
      ...
     ]
    },
    ....
   ]
  },
  ....
 ]
}
}
То есть это один большой глубокий объект в котором мы храним объекты приложения через вложенность без всяких айдишников. Ну а дальше просто рендерим компоненты передавая  каждому компоненту нужный объект
const App () => (
<div>
  ...
  {AppState.user.folders.map(folder=><Folder folder={folder}/>)}
</div>
)

const Folder = ({folder}) => (
<div>
  ...
  {folder.projects.map(project=><Project project={project}/>}
</div>
)


const Project = ({project}) => (
<div>
  ...
  {project.tasks.map(tasks=><Task task={task}/>}
</div>
)
и таким образом каждый компонент получив свой объект может работать с ним как с локальным стором. Например компонент проекта получим объект проекта (<Project project={project}/>) может поменять его имя
const Project = ({project}) => (
<div>
  <input
   value={project.name}
   onChange={()=>
     project.name = e.target.value
  }/>
  ...
</div>
)
В общем получается что с одной стороны все состояние приложения хранится в единственном объекте а с другой стороны каждый компонент может работать со своим объектом/"стором" независимо - читать и обновлять данные (без какой либо централизованной обработки как в редаксе). По удобству это практически не отличается от работы с локальным состоянием компонента при этом имея все преимущества хранения в общем сторе.
источник

Б

Богдан in JavaScript.Ninja
Illya Klymov
с mobx когда данные лежат в пачке разных сторов это очень больно было
Но появляется вопрос - что если компоненту нужно обратиться к данным из других частей состояния приложения? Например компоненту проекта вдруг понадобилось прочитать что-то из родительского объекта папки. Тут можно поступить по разному - можно передавать через пропсы родительский объект папки
<div>
{folder.projects.map(project=
 <Project project={project} folder={folder}/>
)}
</div>
Но если вдруг к папке потребовалось обратиться компоненту задачи то придется пробрасывать через кучу компонентов объект с этой папкой (т.н пробрасывать пропсы)
Можно решить проблему проброса пропсов установкой реакт-контекстов но это все костыли - самое простым и элегантным решением будет записать в поле самого объекта ссылку на его родительский объект при создании.
И таким образом у объекта задачи будет поле .project которое будет ссылаться на проект, дальше у проекта будет поле .folder которое будет ссылаться на объект папки и т.д
В итоге когда мы передали компоненту задачи объект задачи то компонент может по цепочке ссылок на родительские объекты обратиться к любой части состояния приложения сохраняя видимость локального стора
Например в компоненте задачи нужно отобразить стиль в зависимости от того находится задача в проекте а тот в папке с флагом архивации
const Task = ({task}) => (
<div style={{
 background: task.project.folder.archived ? `gray`: `white`
}}>
 <input
   value={task.text}
   onChange={(e)=>
     task.text = e.target.value
   }
 />
 ...
</div>
)
Видите как все просто? C одной стороны можем работать с полученным объектом как с локальным стором и обновлять нужные поля а с другой стороны этот объект является частью дерева глобального состояния и мы можем обратиться к нужной части если просто пройтись по родительским ссылкам task.project.folder.archived ? "..." : "..."
Ну и наконец тот факт что все это состояние одновременно хранится в единственном объекте AppState позволяет получить преимущества работы с состоянием приложения как с единственным объектом - например выполнить сериализацию и сохранить в локал-сторадже и т.д
И поэтому когда говорят что с mobx больно работать потому что это отдельные сторы у меня возникает чувство "wtf" :)
источник

v

vasilich in JavaScript.Ninja
Vladosik
просто перебрать массив и добавить поле со значением каждому объекту?
Да
источник

V

Vladosik in JavaScript.Ninja
1225, не совсем понимаю как правильно это реализовать

   async getFiltersHandler() {
     const response = await getCSMoneyFilters(this.$store);
     console.log(response.data);

     if (response.data) {
       for(let filter in response.data) {
         filter.chip_id = this.filterID++;
       }
       this.filtersArr = response.data;
     }
   },
источник

v

vasilich in JavaScript.Ninja
Выгладит норм. А что не работает?
источник

V

Vladosik in JavaScript.Ninja
источник

v

vasilich in JavaScript.Ninja
Кхм, а тебя не смущает текст ошибки?)
источник