안녕하세요 상훈입니다.

 

Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

 

Vue.js , API, Fetch(), 비동기 통신 간에 에러가 발생하였습니다. 

 

이 에러가 처음에는 제가 오타를 내서 발생한 에러인줄 알았으나(근데 오타도 있었음), 

오타의 문제가 아니었습니다.

 

1. F12 -> Network 를 확인해주세요.

2. api를 가져올 때 주소를 잘못 작성한 것을 저는 확인하였습니다. 

HTTPS:// 를 붙여주지 않아 인터넷 접속을 하지 않고 발생한 에러

그리고 다시 url_base를 사용하니 원활히 출력되었습니다!

 

F12-Network 에서 `200 status`로 잘 얻어왔습니다.

주소 주의하세욤..

vue.js - weather clone-coding ing... 

 

 

이상입니다.

참고

 

React Js: Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

I want to fetch my Json file in react js, for this I am using fetch. But it shows an error Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 What could be the error,...

stackoverflow.com

 

반응형

form
HTML5이후로 action을 작성하지 않아도 된다.
GET 방식과 POST방식이 있다.

====================
input : file

form에 enctype : multipart/form-data 를 무조건 추가.
=> 
form의 method = 무조건 post.
=> contents 를 주소로 보낼 수 없음

HTMLInputElement.files 속성은 선택한 파일(File) 목록을 FileList 객체로 반환합니다.

FileList는 배열처럼 행동하므로, 
length 속성을 사용해 현재 선택한 파일의 수를 알 수 있습니다.

name
파일 이름.
lastModified
파일을 마지막으로 수정한 시각을 나타내는 숫자. UNIX 표준시(1970년 1월 1일 자정)으로부터 지난 시간을 밀리초 단위로 나타낸 값입니다.
lastModifiedDate 
파일을 마지막으로 수정한 시각을 나타내는 Date 객체. 더 이상 사용하지 않아야 합니다. lastModified를 대신 사용하세요.
size
파일의 크기를 바이트 단위로 나타낸 값.
type
파일의 MIME 유형.
webkitRelativePath 
webkitdirectory 특성을 사용한 경우, 기준 디렉토리에 대한 파일의 상대적인 경로. 비표준 특성이므로 사용에 주의가 필요합니다.

accept 특성

반응형
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>
<style>
    #drop_zone {
  border: 5px solid blue;
  width:  400px;
  height: 300px;
}
</style>
<body>
    <h1>How to Drag&Drop File Upload</h1>
    <form method="post" enctype="multipart/form-data">
        <input type="file" id="file" name="file" multiple >
        <div id="drop_zone" ondrop="dropHandler(event);" ondragover="dragOverHandler(event);">
            <p id="drop_zone_item_name_list" class="text-center">파일을 이곳에 끌어다 놓아주세요</p>
        </div>
        <button type="button" onclick="checkForm()" class="btn btn-primary">submit</button>
    </form>
    
<script>
    const dropZone = document.querySelector('#drop_zone')
    let formData = new FormData()   // formData library

    // 들어왔을 때 배경 색 변경
    dropZone.addEventListener('dragover', () => {
        dropZone.style.backgroundColor = 'gray'
    })

    // 나갔을 때 배경 색 복원
    dropZone.addEventListener('dragleave', () => {
        dropZone.style.backgroundColor = 'white'
    })


    function dragOverHandler(ev) {
        console.log('File(s) in drop zone');

        // Prevent default behavior (Prevent file from being opened)
        ev.preventDefault();
    }

    function dropHandler(ev) {
        console.log('File(s) dropped');
        ev.preventDefault();

        if (ev.dataTransfer.items) {
            let drop_zone_item_name_list = document.querySelector('#drop_zone_item_name_list')
            drop_zone_item_name_list.innerHTML = ""

            
            for (let i = 0; i < ev.dataTransfer.items.length; i++) {
                // If dropped items aren't files, reject them
                if (ev.dataTransfer.items[i].kind === 'file') {
                    const file = ev.dataTransfer.items[i].getAsFile();
                    // console.log('... file[' + i + '].name = ' + file.name);
                    drop_zone_item_name_list.innerHTML += file.name + "<br>"    // 리스트에 출력
                    console.log(file)   
                    formData.append('files',file[i]) // formData 에 data 삽입
                }else{
                    console.log('it is not a file')
                }
            }
            console.log('file loop is end')
        } else {
            console.log('use interface')
            // Use DataTransfer interface to access the file(s)
            for (let i = 0; i < ev.dataTransfer.files.length; i++) {
            console.log('... file[' + i + '].name = ' + ev.dataTransfer.files[i].name);
            }
        }
        dropZone.style.backgroundColor = 'white'
    }

    function checkForm() {
        if(formData) {
            $.ajax({
                data: checkForm,
                method: 'post',
                dataType: false,

            })
            .success( console.log('no error'))
            .fail(console.log('fail'))
        }
    }
</script>



</body>
</html>

반응형

안녕하세요 상훈입니다.

Vue.js 3,  Tailwind.css 를 설치하여 프로젝트를 npm run serve 를 통해 실행하였는데 에러가 발생하였습니다.

에러 내용

 ERROR  Failed to compile with 1 error                                                                                                                                                                            오후 6:00:02
 error  in ./src/index.css

Syntax Error: Error: Loading PostCSS Plugin failed: Cannot find module 'tailwindcss'
Require stack:
- D:\Projects\loading-view\noop.js

(@D:\Projects\loading-view\postcss.config.js)
    at Array.map (<anonymous>)


 @ ./src/index.css 4:14-157 15:3-20:5 16:22-165
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://192.168.219.105:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js

 

개략 Tailwindcssmodule을 찾을 수 없다는 문제인데요, 

$ npm install tailwindcss@npm:@tailwindcss/postcss7-compat @tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9

명령어입력(설치)해주신 뒤,

 

module.exports = {
  purge: {  content: ['./public/**/*.html', './src/**/*.vue'] },
  //  ...
}

위의 내용을

 이와 같이 tailwind.config.js 에 작성해주고 저장해주세요.

 

그리고 다시 프로젝트 구동 "npm run serve" 해주시면 정상적으로 실행이 됩니다.

 

이상입니다.

 

 

참고

 

Syntax Error: Error: Loading PostCSS Plugin failed: Cannot find module 'tailwindcss' · Issue #32 · forsartis/vue-cli-plugin-ta

ERROR Failed to compile with 1 error 20:44:08 error in ./src/assets/tailwind.css Syntax Error: Error: Loading PostCSS Plugin failed: Cannot find module 'tailwindcss' Every couple of weeks I...

github.com

 

 

 

반응형

안녕하세요 상훈입니다.

JavascriptPromise에 대해 알아보겠습니다.

내용은 해당 영상을 참고하였습니다.

 

Promiseasync 까지 연결되어 사용하는 내용도 가능합니다.

하지만 이번에는 성공, then() 까지만 확인하도록 하겠습니다.

 

예시) 일반적인 함수 사용하기.

기본적으로 delay라는 함수가 있을 때, 인자로 seccallback을 받습니다. 

함수 내부에는 setTimeout을 이용하여 sec초 뒤에 callback을 출력하는 함수입니다. (시간을 띄울거예요!)

function delay(sec, callback) {
    setTimeout(() => {
        callback (new Date().toISOString())
    }, sec * 1000)
}
delay(1, (result) => {
    console.log(1, result)
})

 

그리고 delay함수를 1초 뒤result 함수로 출력하겠다! 선언하면, 1초 뒤에 

해당 내용 출력

해당 내용이 출력됩니다.

 

만약 이곳에서 여러 개delay함수를 사용하여 쓰고싶다!  이렇다면, 흔히 말하는 콜백지옥함수가 될겁니다.

delay(1, (result) => {
    console.log(1, result)

    delay(1, (result) => {
        console.log(2, result)

        delay(1, (result) => {
            console.log(3, result)

            delay(1, (result) => {
                console.log(4, result)

                delay(1, (result) => {
                    console.log(5, result)
                })
            })
        })
    })
})

결과

결과적으로 잘~ 작동합니다! 하지만, 만약 저 코드 양이 방대해진다면, 본인은 물론 다른 사람도 보다가 미쳐서 모니터를 주먹으로 칠 수도 있습니다.

그래서 나온것이 Promise() 입니다.


 

예시2) Promise() : 여러 개의 then() 사용하기

function delayP(sec) {	// 인자를 시간초만 받음
    return new Promise( ( resolve, reject ) => {    // Promise (성공, 실패) 선언
        setTimeout(() => {
            resolve (new Date().toISOString())  // resolve(성공)에 해당하는 항목
        }, sec * 1000)
    })
}

 

then()

delayP(1)
    .then((result)=> {  
        console.log(1, result)
        return delayP(1)    // delayP() 를 return 시켜 새로운 promise를 실행하는 것. then으로 이어 받을 수 있다.
    })
    .then((result) => { // 2번 째 then을 통해서 위의 첫번째 then이 실행된 이후에 실행. 즉, 1초 + 1초 에 실행된다.
        console.log(2, result)
    })

 Promise() .then() 을 사용하는 것의 장점은 더 말할 필요가 없이 보기가 쉽습니다. 

또한 구분지어서 코드를 작성하는데에도 문제가 없죠. 

출력 결과

 

 

하지만 만약 반환값(return)을 작성해주지 않는다면,

delayP(1)
    .then((result)=> {  
        console.log(1, result)
        return delayP(1)    // delayP() 를 return 시켜 새로운 promise를 실행하는 것. then으로 이어 받을 수 있다.
    })
    .then((result) => { // 2번 째 then을 통해서 위의 첫번째 then이 실행된 이후에 실행. 즉, 1초 + 1초 에 실행된다.
        console.log(2, result)
        // return이 없다. => 다음 result = undefined가 될 것이다.
        // return 'string or something' 하면 해당하는 내용이 바로 출력된다. 
            // => delay를 통해 해당 내용을 지연시키지 않았기 때문에.
    })
    .then((result) => { // 받은 return 값이 null 이기 때문에 undefined를 출력한다.
        console.log(3, result)  // 출력 내용 ( 3, undefined )
    })

2번째 then에서 return없습니다!

=> 3번째 delayP( null ) 이 들어갔다는 뜻입니다.

그렇기 때문에 출력되는 것은 ( 3, undefined ) 가 됩니다.

출력 결과

추가적으로 sec 라는 인자도 전달이 안되었기 때문
바로 세번째 then() 이 실행되어 3, result 가 출력되었습니다.

2, 3번째 then()을 보기쉽게 해보자면, 아래와 같습니다.

    .then((result) => {
        console.log(2, result)
        console.log(3, result)  
    })

물론 2번째 then true라는 전제조건이 존재하지만요.

 

이상으로 promise 기초에 대한 포스팅을 마치겠습니다.

감사합니다.

 

 

참고

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise

 

Promise - JavaScript | MDN

Promise 객체는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타냅니다.

developer.mozilla.org

 

 

 

반응형

안녕하세요 상훈입니다.

Vue cli 3 를 유튜브로 클론코딩 하였습니다.

해당 강의 링크 및 영상

위는 해당하는 강의 내용입니다.

 

Vue.js 버전은 3.2.20 이고, 
Vue/cli4.~ 입니다. 

Vue.js version description

 

styletailwind.css를 사용하였고,
추가된 라이브러리는 moment.js 로, datetime을 출력할 수 있는 자바스크립트 라이브러리입니다. 

tailwind
구현내용 header

일단 결과적으로 문제가 한 개 있었는데 고치지 못하였습니다. ㅎㅎ;;

moment.js 관련해서 인 것같은데 어떻게 해야할지 모르겠더군요. 

=> 원작 개발자님의 소스를 보아도 아예 포맷이 달라, 결론을 얻어내지 못하였습니다.

좌 : 내 프로젝트  /  우 : 원작 프로젝트(수정된듯)
해당하는 에러

발생한 에러는 dataDate(현재시각)관련해서의 에러인데... 타입에러가 발생하였고, 프로퍼티가 선언되지 않았다고 합니다.

분명 main vue 에서
1. 변수 선언
2. DataTitle.vue 에서 props로 참조해주어
3. data 출력을 진행하였지만 해당되는 내용에 에러가 발생하였습니다. 

언젠가 이게 무슨 원리로 제대로 작동하는지 이해해서 수정할 수 있을거라 생각합니다......ㅎ.ㅎ..


결과화면

국가를 선택하기 전 : Global 설정.
현재

select-option을 이용하여 해당 내역을 모두 불러올 수 있고, 이를 computed 처리하여 실시간으로 데이터가 전환됩니다. 

button - Clear Country 하면 다시 Global을 나타냅니다. (=초기화)

 

모바일 화면에서는 이렇게 출력될겁니다.

 

 


이렇게 프로젝트를 따라 만들어보면서 느낀것이 

1. vue.js 에 대해 이제 알아듣는 것 보니 걸음마는 떼었다.
2. async await에 대해 공부를 좀 해야겠습니다.

이상입니다.

수고!

 

사용

 

Icon Loading GIF - Find & Share on GIPHY

Discover & share this Icon GIF with everyone you know. GIPHY is how you search, share, discover, and create GIFs.

giphy.com

코로나 api

 

Coronavirus COVID19 API

The Postman Documenter generates and maintains beautiful, live documentation for your collections. Never worry about maintaining API documentation again.

documenter.getpostman.com

 

Moment.js | Docs

moment.relativeTimeThreshold(unit); // getter moment.relativeTimeThreshold(unit, limit); // setter duration.humanize has thresholds which define when a unit is considered a minute, an hour and so on. For example, by default more than 45 seconds is consider

momentjs.com

 

Vue에서 moment사용하기 (feat. vue-moment)

자바스크립트에서 거의 표준으로 사용되고 있는 날짜관련 라이브러리인 Moment 를 Vue에서 쉽게 사용할 수 있는 라이브러리가 있습니다. vue-moment 는 Vue에서 필터 형식으로 Moment를 사용할 수 있게

ux.stories.pe.kr

 

async와 await를 사용하여 비동기 프로그래밍을 쉽게 만들기 - Web 개발 학습하기 | MDN

Javascript에 대한 최신 추가 사항은 ECMAScript 2017 JavaScript 에디션의 일부인 async functions 그리고 await 키워드는 ECMAScript2017에 추가되었습니다. 이 기능들은 기본적으로 비동기 코드를 쓰고 Promise를

developer.mozilla.org

프로젝트전체

 

GitHub - bradtraversy/vue-covid-tracker: Simple tracker for Covid-19 cases and deaths

Simple tracker for Covid-19 cases and deaths. Contribute to bradtraversy/vue-covid-tracker development by creating an account on GitHub.

github.com

,

반응형

안녕하세요 상훈입니다.

우리의 WebApplication을 조금이라도 더 예쁘게 꾸며줄 css - transition을 포스팅하겠습니다.

간단한 설명과 함께 화면 구성

 

그 중 hover의 이벤트를 사용하려고 합니다.

html에서는 클래스명만 정해주시면 됩니다.

<body>
    <p>width, height, bg-color, transform 을 위한 트랜지션 결합.</p>
    <div class="transform"></div>
</body>

클래스명 "transform"에 대해서 아래의 style을 지정해주면 됩니다.

<style>
.transform{
    border: 1px solid black;
    display: block;
    width: 100px;
    height: 100px;
    background-color: #0000FF;
    
    -webkit-transition: width 2s, height 2s, background-color 2s, -webkit-transform 2s;
    transition: width 2s, height 2s, background-color 2s, transform 2s;
}

.transform:hover {
    background-color: #FFCCCC;
    width:200px;
    height:200px;
    -webkit-transform: rotate(180deg);
    transform: rotate(180deg);
}
</style>

 

rotate를 보시면 아시다시피 transitiontransform으로 지정한 내용을 살펴보면,

 

2초동안 [ 가로 200px, 세로 200px, 배경색 #FFCCCC, 180도 회전 ] 을 하게됩니다.

결과물

이상입니다.

해당 내용은 전부 'MDN WebDocs' 에 작성되어져 있습니다.

 

CSS 트랜지션 사용하기 - CSS: Cascading Style Sheets | MDN

CSS 트랜지션은 CSS 속성을 변경할 때 애니메이션 속도를 조절하는 방법을 제공합니다. 속성 변경이 즉시 영향을 미치게 하는 대신, 그 속성의 변화가 일정 기간에 걸쳐 일어나도록 할 수 있습니

developer.mozilla.org

 

 

 

반응형

안녕하세요 상훈입니다.

Vue.js + tailwind.css 를 이용하여 모달창을 구현하도록 하겠습니다.

컴포넌트의 개념을 첨가하였으니, 양해바랍니다. (컴포넌트 넣을줄만 알면 됨)

모달창 구현하기

 

<template >
  <div
    v-if="ModalDisplay"
    class="shadow-lg w-full h-full flex bg-black bg-opacity-70 justify-center align-middle items-center ">
      <div class="w-1/3 h-1/2 bg-white rounded relative">
        <div class="relative w-full">
            <div class="flex text-center items-center justify-center pt-2">
                <h1 class="font-bold text-2xl">모달창 레이아웃</h1>
            </div>
            <svg 
                @click="ModalDisplay = false" 
                id="closeModalBtn" xmlns="http://www.w3.org/2000/svg" class=" cursor-pointer h-10 w-10 absolute top-0 right-0 hover:text-red-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
            </svg>
        </div>
        <div class="w-full pt-5">
            <hr>
            <p class="py-5 px-5 text-xl">
                안녕하십니까?<br>
                모달창입니다.
            </p>
        </div>
        <div class="w-full">
            <button
                @click="ModalDisplay = false" 
                class="absolute bottom-0 right-0 border border-solid round w-24 h-10  my-2 mx-3 hover:text-red-700 hover:border-red-500" >
            닫기</button>
        </div>
      </div>
  </div>
</template>

<script>
export default {
    data() {
        return {
            ModalDisplay: true,
        }
    }
}
</script>

<style>

</style>

 

 

v-if @click 바인딩으로 해당 기능을 구현하였습니다.

 

ModalDisplay기본값으로 true로 해서 자동적으로 출력되어져있게 해놓고,
닫기 버튼이나, X버튼을 눌렀을 때 종료가 되게 하는 겁니다. 

 

svgbutton으로 감싸서 button으로 바꾸는게 용도에 맞아 좋아보입니다.

 

모달창 구현하기 완성

 


혹시나해서 App.vue 도 게시

<template>
  <Modal />

</template>

<script>
import Modal from './components/Modal.vue';

export default {
  components: {
    Modal,
  },
}
</script>

<style>

</style>

 

반응형

+ Recent posts