fix: setAttribute error in the js package (#3099)

This commit is contained in:
Anshuman Pandey
2024-09-05 14:53:49 +05:30
committed by GitHub
parent 538c1bd809
commit 954c435404
4 changed files with 74 additions and 13 deletions

View File

@@ -16,7 +16,7 @@ export default function App(): JSX.Element {
const config = {
environmentId: process.env.EXPO_PUBLIC_FORMBRICKS_ENVIRONMENT_ID,
apiHost: process.env.EXPO_PUBLIC_API_HOST,
userId: "random user id",
userId: "random-user-id",
attributes: {
language: "en",
testAttr: "attr-test",

View File

@@ -4,13 +4,10 @@ import { MissingPersonError, NetworkError, Result, err, ok, okVoid } from "../..
import { Logger } from "../../shared/logger";
import { AppConfig } from "./config";
const appConfig = AppConfig.getInstance();
const logger = Logger.getInstance();
export const updateAttribute = async (
key: string,
value: string,
appConfig: AppConfig
): Promise<Result<void, NetworkError>> => {
export const updateAttribute = async (key: string, value: string): Promise<Result<void, NetworkError>> => {
const { apiHost, environmentId, userId } = appConfig.get();
const api = new FormbricksAPI({
@@ -109,8 +106,7 @@ export const isExistingAttribute = (key: string, value: string, appConfig: AppCo
export const setAttributeInApp = async (
key: string,
value: any,
appConfig: AppConfig
value: any
): Promise<Result<void, NetworkError | MissingPersonError>> => {
if (key === "userId") {
logger.error("Setting userId is no longer supported. Please set the userId in the init call instead.");
@@ -124,7 +120,7 @@ export const setAttributeInApp = async (
return okVoid();
}
const result = await updateAttribute(key, value.toString(), appConfig);
const result = await updateAttribute(key, value.toString());
if (result.ok) {
// udpdate attribute in config

View File

@@ -0,0 +1,64 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access -- required */
/* eslint-disable @typescript-eslint/no-dynamic-delete -- required */
import { FormbricksAPI } from "@formbricks/api";
import type { TAttributes } from "@formbricks/types/attributes";
import { type Result, err, ok } from "@formbricks/types/error-handlers";
import type { NetworkError } from "@formbricks/types/errors";
import { Logger } from "../../../js-core/src/shared/logger";
import { appConfig } from "./config";
const logger = Logger.getInstance();
export const updateAttributes = async (
apiHost: string,
environmentId: string,
userId: string,
attributes: TAttributes
): Promise<Result<TAttributes, NetworkError>> => {
// clean attributes and remove existing attributes if config already exists
const updatedAttributes = { ...attributes };
try {
const existingAttributes = appConfig.get().state.attributes;
for (const [key, value] of Object.entries(existingAttributes)) {
if (updatedAttributes[key] === value) {
delete updatedAttributes[key];
}
}
} catch (e) {
logger.debug("config not set; sending all attributes to backend");
}
// send to backend if updatedAttributes is not empty
if (Object.keys(updatedAttributes).length === 0) {
logger.debug("No attributes to update. Skipping update.");
return ok(updatedAttributes);
}
logger.debug(`Updating attributes: ${JSON.stringify(updatedAttributes)}`);
const api = new FormbricksAPI({
apiHost,
environmentId,
});
const res = await api.client.attribute.update({ userId, attributes: updatedAttributes });
if (res.ok) {
return ok(updatedAttributes);
}
// @ts-expect-error -- required because we set ignore
if (res.error.details?.ignore) {
logger.error(`Error updating person with userId ${userId}`);
return ok(updatedAttributes);
}
return err({
code: "network_error",
status: 500,
message: `Error updating person with userId ${userId}`,
url: new URL(`${apiHost}/api/v1/client/${environmentId}/people/${userId}/attributes`),
responseMessage: res.error.message,
});
};

View File

@@ -1,6 +1,5 @@
import { type TAttributes } from "@formbricks/types/attributes";
import { type TJSAppConfig, type TJsAppConfigInput } from "@formbricks/types/js";
import { updateAttributes } from "../../../js-core/src/app/lib/attributes";
import { sync } from "../../../js-core/src/app/lib/sync";
import {
ErrorHandler,
@@ -14,6 +13,7 @@ import {
} from "../../../js-core/src/shared/errors";
import { Logger } from "../../../js-core/src/shared/logger";
import { trackAction } from "./actions";
import { updateAttributes } from "./attributes";
import { appConfig } from "./config";
let isInitialized = false;
@@ -55,12 +55,13 @@ export const initialize = async (
// if userId and attributes are available, set them in backend
let updatedAttributes: TAttributes | null = null;
if (c.userId && c.attributes) {
const res = await updateAttributes(c.apiHost, c.environmentId, c.userId, c.attributes, appConfig);
const res = await updateAttributes(c.apiHost, c.environmentId, c.userId, c.attributes);
if (!res.ok) {
return err(res.error);
return err(res.error) as unknown as Result<void, MissingFieldError | NetworkError | MissingPersonError>;
}
updatedAttributes = res.value;
updatedAttributes = res.data;
}
let existingConfig: TJSAppConfig | undefined;